Closed lucasmation closed 6 months ago
Boa! Vou incorporar isso nas funções. Eu já fazia essa deduplicação numa etapa de pré-processamento das bases que usei como teste, não sei por que não incluí nas funções direto hehe
Ok, provavelmente não fiz isso porque nenhuma base que tava usando como teste tem tantas observações duplicadas assim.
Testei aqui com a RAIS: das 3~ milhões de observações, tirei uma amostra de 200k. Desses 200k, 188k são únicos. Os ganhos ficam muito baixos (padronizar_logradouros2()
é a otimizada):
bench::mark(padronizar_logradouros(hehe), padronizar_logradouros2(hehe), iterations = 5)
#> # A tibble: 2 × 13
#> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list> <list> <list> <list>
#> 1 padronizar_logradouros(hehe) 16.2s 16.4s 0.0609 9.2MB 0 5 0 1.37m <chr> <Rprofmem> <bench_tm [5]> <tibble>
#> 2 padronizar_logradouros2(hehe) 15.9s 16.1s 0.0621 21.7MB 0 5 0 1.34m <chr> <Rprofmem> <bench_tm [5]> <tibble>
Testando com uma amostra de 1 milhão de observações, 867k únicas:
bench::mark(padronizar_logradouros(hehe), padronizar_logradouros2(hehe), iterations = 5)
#> # A tibble: 2 × 13
#> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list> <list> <list> <list>
#> 1 padronizar_logradouros(hehe) 1.25m 1.31m 0.0128 45.8MB 0.00319 4 1 5.22m <chr> <Rprofmem> <bench_tm [5]> <tibble>
#> 2 padronizar_logradouros2(hehe) 1.11m 1.12m 0.0148 100.5MB 0 5 0 5.63m <chr> <Rprofmem> <bench_tm [5]> <tibble>
Como esperado, quanto maior o número de duplicatas, maior a economia de tempo. Testei com a função padronizar_municipios()
também, que recebe muito mais valores duplicados, e o tempo de processamento pra 3~ milhões de registros foi de 10s pra 0.3s, 30~ vezes mais rápido.
Edit: exemplo com a padronizar_estados()
:
bench::mark(padronizar_estados(rais$uf), padronizar_estados2(rais$uf), iterations = 5)
#> # A tibble: 2 × 13
#> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list> <list> <list> <list>
#> 1 padronizar_estados(rais$uf) 7.68s 9.14s 0.114 829MB 0.228 5 10 43.95s <chr> <Rprofmem> <bench_tm [5]> <tibble>
#> 2 padronizar_estados2(rais$uf) 243.48ms 245.51ms 2.06 173MB 0.826 5 2 2.42s <chr> <Rprofmem> <bench_tm [5]> <tibble>
@rafapereirabr, @dhersz , ta bacana, mas um pouco lento, seria bom melhorar a performance
Sugiro: (1) primeiro agregar/deduplicar o vetor. (2) aplicar o filtro (REGEX) na base deduplicada. (3) fazer um merge para recompor as observações do vetor original. Isso deve acelerar bem.
Motivaçao: na base do CPF tem 193 observações com logradouro não nulo. Mas apenas 19.8 milhões de logradouros únicos (pre harmonização). Este problema padrão deve ser comum para várias bases de endereços.
Segue um proto-código para fazer isso:
talvez tenha uma forma mais eficiente de fazer esta funcao externa, sem precisar do DT. Mas com DT deve funcionar (nao testei, servidor ta travado rodando a funcao original)
EDIT: so para ilustar os ganhos: