Data.table: operação de junção quase 2 vezes mais lenta

Criado em 2 out. 2019  ·  29Comentários  ·  Fonte: Rdatatable/data.table

Oi, eu estava testando
data.table_1.10.4-3 + R versão 3.4.0 (2017-04-21)
vs
data.table_1.12.2 + R versão 3.6.1 (2019-07-05)

e notei que a operação de junção é quase 2 vezes mais lenta na nova versão data.table (R?)
Eu acho que depende principalmente da versão do data.table

rm(list=ls())

library(data.table)
library(tictoc)


aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

#aa[,  a1 := as.character(a)]
#bb[,  a1 := as.character(a)]

setindex(aa, a)
setindex(bb, a)

tic()
for(i in c(1:1000)) {
 # aa[bb, b := i.b, on=.(a, a1)] # test1
  aa[bb, b := i.b, on=.(a)] # test2
}
toc()

# test1
# 3.6.1: 5.5 sec with index
# 3.6.1: 6.87 sec without index
# 3.4.0: 3.02 sec (no index)

# test2
# 3.6.1: 3.82 sec with index
# 3.6.1: 4.44 sec without index
# 3.4.0: 2.48 sec (no index)
High joins performance regression

Todos 29 comentários

Já executei o seguinte:

# run_join_time.sh
echo 'hash,time' > 'join_timings.csv'

for HASH in $(git rev-list --ancestry-path 1.10.0..1.12.4 | awk 'NR == 1 || NR % 10 == 0');
do git checkout $HASH && R CMD INSTALL . && Rscript time_join.R $HASH;
done
# time_join.R
library(data.table)
library(microbenchmark)

hash = commandArgs(trailingOnly = TRUE)

aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

fwrite(data.table(
  hash = hash,
  time = microbenchmark(times = 1000L, aa[bb, b := i.b, on=.(a)])$time
), 'join_timings.csv', append = TRUE)

Em seguida, fiz o seguinte para criar este enredo

Screenshot 2019-10-03 at 6 59 11 PM

library(data.table)
times = fread('join_timings.csv')

times[ , date := as.POSIXct(system(sprintf("git show --no-patch --no-notes --pretty='%%cd' %s", .BY$hash), intern = TRUE), by = hash]
times[ , date := as.POSIXct(date, format = '%a %b %d %T %Y %z', tz = 'UTC')]
times[ , date := as.IDate(date)]
setorder(times, date)

tags = system('
for TAG in $(git tag);
  do git show --no-patch --no-notes --pretty="$TAG\t%cd" $TAG;
done
', intern = TRUE)

tags = setDT(tstrsplit(tags, '\t'))
setnames(tags, c('tag', 'date'))
tags[ , date := as.POSIXct(date, format = '%a %b %d %T %Y %z', tz = 'UTC')]
tags[ , date := as.IDate(date)]

times[ , {
  par(mar = c(7.1, 4.1, 2.1, 2.1))
  y = boxplot(I(time/1e6) ~ date, log = 'y', notch = TRUE, pch = '.',
              las = 2L, xlab = '', ylab = 'Execution time (ms)', cex.axis = .8)
  x = unique(date)
  idx = findInterval(tags$date, x)
  abline(v = idx[idx>0L], lty = 2L, col = 'red')
  text(idx[idx>0L], .7*10^(par('usr')[4L]), tags$tag[idx>0L], 
       col = 'red', srt = 90)
  NULL
}]


Depois de começar, percebi que poderia simplificar um pouco isso usando

echo 'hash,time,date' > 'join_timings.csv'

for HASH in $(git rev-list --ancestry-path 1.10.0..1.12.4 | awk 'NR == 1 || NR % 10 == 0');
do git checkout $HASH && R CMD INSTALL . --preclean && Rscript time_join.R $HASH $(git show --no-patch --no-notes --pretty='%cd' $HASH);
done
library(data.table)
library(microbenchmark)

args = commandArgs(trailingOnly = TRUE)
hash = args[1L]
date = as.POSIXct(args[2L], format = '%a %b %d %T %Y %z', tz = 'UTC'))

aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

fwrite(data.table(
  hash = hash,
  date = date,
  time = microbenchmark(times = 1000L, aa[bb, b := i.b, on=.(a)])$time
), 'join_timings.csv', append = TRUE)

para adicionar o tempo de confirmação diretamente ao benchmark

join_timings.txt

Oi MichaelChirico, eu li duas vezes
mas o que significa exatamente a linha do tempo de 2016 a 2019? É uma versão do datatable?

não apenas versões, mas commits específicos. deixe-me tentar adicionar alguma demarcação de versões, uma boa ideia eu esqueci de adicionar

@MichaelChirico seu gráfico parece super legal, o que estava faltando era uma interpretação disso :) Por adivinhar, eu diria que o novo forder paralelo é mais lento para uma entrada de comprimento 100 do que era antes. Qual IMO está bem, porque ainda são microssegundos. É claro que vale a pena reduzir a sobrecarga, mas a prioridade deve ser a redução de recursos nos cenários de uso mais comuns. Fazer um loop 10.000 vezes em uma entrada de comprimento 100 definitivamente não é um desses.

esse foi o meu palpite também depois de ver o 1.12.0 NEWS. tentará executar novamente o single threaded.

@jangorecki , se você fizer as contas simples, são milhares de microssegundos, ou seja, milissegundos
A inspiração deste teste foi o meu projeto atual onde junto 7-8 tabuadas com 40 000 linhas
Antes leva 18 segundos, depois leva 40 segundos
Meu teste também inclui chave de caractere
Eu instalei 3.6+1.12 e depois voltei para 3.4+1.10
Eu acho que isso não é uma situação normal, é por isso que esse problema está aqui

Sim, o gráfico é realmente incrível; devemos fazer mais disso e automatizá-lo.

Mas o relatório original compara R 3,4 com R 3,6, que tem R 3,5 no meio. Sabemos que o R 3.5 impactou data.table através da alteração de REAL(), INTEGER() de ALTREP de macros para funções (um pouco mais pesadas).

@ vk111 Você pode reexecutar seus testes com a v1.12.4 agora no CRAN. Melhor? Estamos usando loops externos da API R para lidar com o R 3.5+. Como próximo passo, seria ótimo saber como você encontra a v1.12.4. Você também pode incluir mais informações sobre sua máquina; por exemplo, sistema operacional, RAM e número de CPU.

@matt , vai fazer

Olá @mattdowle ,

Eu atualizei para 1.12.4 (+ R 3.6.1) - basicamente existem os mesmos números para teste de unidade e meu func
Vou considerar aqui apenas junções com caractere sem indexação - como referência
Teste de unidade (como mencionado no primeiro post)
3.6.1: 6,87 segundos sem índice
3.4.0: 3,02 segundos (sem índice)

Minha função do projeto permanece a mesma: 20 vs 40 segundos
Consiste apenas em ~14 dt joins
duas tabelas 30.000 linhas (dt1) e 366.000 linhas (dt2)
15 colunas cada
chave é de 2 caracteres e 1 numérico
e atribuídos 7 campos (de dt1 a dt2) durante a junção

meu PC:
Ganhe 10 64 bits
AMD A8 2,2 Ghz
8 GB de RAM

cmd: wmic cpu get NumberOfCores, NumberOfLogicalProcessors/ Formato:List
NumberOfCores=4
NumberOfLogicalProcessors=4

Obrigado pela sua análise

Oi @mattdowle , então você está considerando isso?

De acordo com um git bisect que acabei de executar novamente, esse commit é "culpado" pela desaceleração, espero que isso possa ajudar Matt a encontrar a raiz. O fato de estar relacionado a forder me deixa relativamente confiante de que o fixamos corretamente.

https://github.com/Rdatatable/data.table/commit/e59ba149f21bb35098ed0b527505d5ed6c5cb0db

Mais precisamente:

# run_join_time.sh
R CMD INSTALL . && Rscript time_join.R
# time_join.R
library(data.table)
library(microbenchmark)

aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

summary(microbenchmark(times = 1000L, aa[bb, b := i.b, on=.(a)])$time/1e6)

Com esses dois scripts, de master/HEAD :

git checkout 1.12.0
git bisect start
git bisect bad
git bisect good 1.11.8

Então, a cada iteração, execute sh run_join_time.sh e verifique o resultado. Os commits bad estavam demorando aproximadamente 0,9 segundos por iteração na minha máquina, os commits good cerca de 0,7.

Oi Michael, obrigado, mas o desempenho caiu drasticamente, especialmente
para chave de caractere-I fornecido com o teste de unidade no primeiro post
De qualquer forma, acho que precisamos esperar a confirmação de Matt se foi corrigido em
nova versão ou não

Em qui, 26 de dezembro de 2019 às 15:02, Michael Chirico [email protected]
escreveu:

De acordo com um git bisect que acabei de executar novamente, este commit é "culpado" pelo
diminua a velocidade, espero que isso possa ajudar Matt a encontrar a raiz. É isso aí
relacionado ao forder me deixa relativamente confiante de que o fixamos
corretamente.

e59ba14
https://github.com/Rdatatable/data.table/commit/e59ba149f21bb35098ed0b527505d5ed6c5cb0db

Mais precisamente:

run_join_time.sh

R CMD INSTALAR . && Rscript time_join.R

time_join.R

biblioteca(data.table)
biblioteca (microbenchmark)

aa = dados.tabela(a = seq(1.100), b = rep(0, 100))
bb = dados.tabela(a = seq(1.100), b = rep(1, 100))

resumo(microbenchmark(vezes = 1000L, aa[bb, b := ib, on=.(a)])$time/1e6)

Com esses dois scripts, do master/HEAD:

git checkout 1.12.0
git bisect start
git bisect ruim
git bisect bom 1.11.8

Em seguida, em cada iteração, execute sh run_join_time.sh e verifique o resultado. O
commits ruins estavam levando cerca de 0,9 segundos por iteração na minha máquina,
bons confirma cerca de 0,7.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MJQITNUZDNYV7NTIX3Q2S2ORA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHVTR4Q#issuement-5
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MOTZRFFM2QKVFUHT6LQ2S2ORANCNFSM4I4ZPREA
.

>

Atenciosamente,
Vasily Kuznetsov

@ vk111 se este problema não estiver fechado, você pode assumir com segurança que o problema ainda não foi corrigido. Sempre que corrigimos algo, fechamos o problema relacionado.

@vk111 você pode mitigar com alguns pequenos ajustes usando setkey em vez de setindex . Isso reduz seu teste em mais da metade no meu computador:

aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

aa[,  a1 := as.character(a)]
bb[,  a1 := as.character(a)]

tic()
for(i in c(1:1000)) {
  aa[bb, b := i.b, on=.(a, a1)] # test1 without key
}
toc()
## 4 sec elapsed

tic()
setkey(aa, a, a1)
setkey(bb, a, a1)

for(i in c(1:1000)) {
  aa[bb, b := i.b] # test2 without key
}
toc()
## 1.46 sec elapsed

image

library(microbenchmark)
library(data.table)

aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))

aa[,  a1 := as.character(a)]
bb[,  a1 := as.character(a)]

aa_nokey = copy(aa)
bb_nokey = copy(bb)

tic()
aa_int_key = setkey(copy(aa), a)
bb_int_key = setkey(copy(bb), a)
toc()

tic()
aa_int_char = setkey(copy(aa), a, a1)
bb_int_char = setkey(copy(bb), a, a1)
toc()
int_nokey = function(dt1, dt2){
  dt1[dt2, b := i.b, on=.(a)]
}

int_key = function(dt1, dt2){
  dt1[dt2, b := i.b]
}

int_char_nokey = function(dt1, dt2){
  dt1[dt2, b := i.b, on=.(a, a1)]
}

int_char_key = function(dt1, dt2){
  dt1[dt2, b := i.b]
}

int_char_key_on = function(dt1, dt2){
  dt1[dt2, b := i.b, on=.(a, a1)]
}

boxplot(
  microbenchmark(
    a_no_key = int_nokey(aa, bb),
    a_key = int_key(aa_int_key, bb_int_key),
    a_a1_no_key = int_char_nokey(aa, bb),
    a_a1_key = int_char_key(aa_int_char, bb_int_char),
    a_a1_key_on = int_char_key_on(aa_int_char, bb_int_char)
  )
)

Oi Cole, sim, eu sei sobre setkey - eu forneci acima da breve descrição
do meu projeto e não há propósito de 1.000 junções - existem 10-20
junta e a coisa é que minhas cadeias de caracteres são muito dinâmicas e eu
precisa fazer setkey toda vez antes de juntar como 20 vezes setkey e 20
vezes junta e, portanto, o ganho de tempo é inferior a 2 vezes
Eu vivo com 3.4.0 por um tempo como uma solução geral para essa situação
e provavelmente não é grande coisa corrigi-lo em uma nova versão, especialmente se
há um commit culpado encontrado
A propósito, se compararmos maçãs com maçãs, acho que 3,4 (1,10) será
ainda mais rápido que 3.6(1.12) se eu usar o mesmo teste de unidade com o setkey para
ambas as versões
Boas festas

No domingo, 29 de dezembro de 2019, 14:48 Cole Miller, [email protected] escreveu:

@vk111 https://github.com/vk111 você pode mitigar com alguns
pequenos ajustes usando setkey em vez de setindex. Isso corta seu teste por
mais da metade no meu computador:

aa = dados.tabela(a = seq(1.100), b = rep(0, 100))
bb = dados.tabela(a = seq(1.100), b = rep(1, 100))

aa[, a1 := as.caractere(a)]
bb[, a1 := as.caractere(a)]

tic()
for(i em c(1:1000)) {
aa[bb, b := ib, on=.(a, a1)] # teste1 sem chave
}
toc()

4 segundos decorridos

tic()
setkey(aa,a,a1)
setkey(bb, a, a1)

for(i em c(1:1000)) {
aa[bb, b := ib] # teste2 sem chave
}
toc()

1,46 segundos decorridos

[imagem: imagem]
https://user-images.githubusercontent.com/57992489/71557665-126d7880-2a17-11ea-8664-21a10deb47ca.png

biblioteca (microbenchmark)
biblioteca(data.table)

aa = dados.tabela(a = seq(1.100), b = rep(0, 100))
bb = dados.tabela(a = seq(1.100), b = rep(1, 100))

aa[, a1 := as.caractere(a)]
bb[, a1 := as.caractere(a)]

aa_nokey = copiar(aa)
bb_nokey = copiar(bb)

tic()
aa_int_key = setkey(copiar(aa), a)
bb_int_key = setkey(copiar(bb), a)
toc()

tic()
aa_int_char = setkey(copy(aa), a, a1)
bb_int_char = setkey(copy(bb), a, a1)
toc()
int_nokey = function(dt1, dt2){
dt1[dt2, b := ib, em=.(a)]
}

tecla_int = function(dt1, dt2){
dt1[dt2, b := ib]
}

int_char_nokey = function(dt1, dt2){
dt1[dt2, b := ib, on=.(a, a1)]
}

int_char_key = function(dt1, dt2){
dt1[dt2, b := ib]
}

int_char_key_on = function(dt1, dt2){
dt1[dt2, b := ib, on=.(a, a1)]
}

boxplot(
microbenchmark(
a_no_key = int_nokey(aa, bb),
a_key = int_key(aa_int_key, bb_int_key),
a_a1_no_key = int_char_nokey(aa, bb),
a_a1_key = int_char_key(aa_int_char, bb_int_char),
a_a1_key_on = int_char_key_on(aa_int_char, bb_int_char)
)
)


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MPU64YBK7UNT3O3OYDQ3CTBRA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHY73VA#issuecomment-4
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MKSP6LCUJD2HOAG7D3Q3CTBRANCNFSM4I4ZPREA
.

Há um PR #4370 pendente que está relacionado. Pode fazer join com menos overhead que [ normalmente impõe. Ele reduz o tempo do seu exemplo por um fator de 2. Quanto maiores os dados, menor a melhoria, mas por outro lado, quanto mais iterações, melhor a melhoria. Observe que não há como atualizar a coluna durante a junção. Você basicamente tem que adicionar colunas durante a junção e, em seguida, usar algo como fcoalesce , mas isso deve funcionar.
Deve obter alguma velocidade extra uma vez que o #4386 também será mesclado.

library(data.table)
aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))
setindex(aa, a)
setindex(bb, a)
p = proc.time()[[3L]]
for (i in c(1:1000)) {
  aa[bb, b := i.b, on=.(a)]
}
proc.time()[[3L]]-p
#[1] 1.1

lista de mesclagem #4370

library(data.table)
aa = data.table(a = seq(1,100), b = rep(0, 100))
bb = data.table(a = seq(1,100), b = rep(1, 100))
setindex(aa, a)
setindex(bb, a)
p = proc.time()[[3L]]
for (i in c(1:1000)) {
  mergelist(list(aa, bb), on="a")
}
proc.time()[[3L]]-p
#[1] 0.696

Oi Jan, tudo bem obrigado

Quanto maiores os dados, menor a melhoria, mas, por outro lado,
quanto mais iterações, melhor melhoria
O verdadeiro problema está relacionado a big data e algumas iterações - eu escrevi
acima

Em segunda-feira, 4 de maio de 2020, 00:33 Jan Gorecki, [email protected] escreveu:

Há um PR #4370 pendente
https://github.com/Rdatatable/data.table/pull/4370 que está relacionado. Isto
pode fazer join com menos overhead que [ normalmente impõe. Ele reduz a
tempo do seu exemplo por um fator de 2. Quanto maiores os dados, menor
a melhoria, mas por outro lado, quanto mais iterações, melhor
melhoria. Observe que não há como atualizar a coluna durante a junção. Você
basicamente tem que adicionar colunas durante a junção e, em seguida, usar algo como
fcoalesce, mas isso deve ser eficiente.
Deve obter alguma velocidade extra uma vez #4386
https://github.com/Rdatatable/data.table/pull/4386 também será mesclado.

library(data.table)aa = data.table(a = seq(1.100), b = rep(0, 100))bb = data.table(a = seq(1.100), b = rep(1, 100))
setindex(aa,a)
setindex(bb, a)p = proc.time()[[3L]]for (i in c(1:1000)) {
aa[bb, b := ib, em=.(a)]
}
proc.time()[[3L]]-p#[1] 1.1

mergelist #4370 https://github.com/Rdatatable/data.table/pull/4370

library(data.table)aa = data.table(a = seq(1.100), b = rep(0, 100))bb = data.table(a = seq(1.100), b = rep(1, 100))
setindex(aa,a)
setindex(bb, a)p = proc.time()[[3L]]for (i in c(1:1000)) {
mergelist(list(aa, bb), on="a")
}
proc.time()[[3L]]-p#[1] 0,696


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-623193573 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MJR5THRHE3FIXXV3YTRPXWNNANCNFSM4I4ZPREA
.

Verifiquei se #4440 (fundido ontem) resolve esse problema, mas parece que não. Embora os tempos que estou chegando aqui sejam bem diferentes dos tempos relatados por @vk111 , portanto, se você puder testar a versão de desenvolvimento recente e ver se isso faz alguma diferença para o seu fluxo de trabalho, isso seria útil.
Como você está no Windows, há outro PR pendente que pode eventualmente ajudar #4558.


Este é o script comum que executo em cada ambiente:

library(data.table)
setDTthreads(2) ## vk111 has 4 cores
aa = data.table(a = seq(1,100), b = rep(0, 100))[,  a1 := as.character(a)]
bb = data.table(a = seq(1,100), b = rep(1, 100))[,  a1 := as.character(a)]
setindex(aa, a); setindex(bb, a)
cat("test1\n")
system.time({
for(i in c(1:1000)) {
  aa[bb, b := i.b, on=.(a, a1)] # test1
}})
cat("test2\n")
system.time({
for(i in c(1:1000)) {
  aa[bb, b := i.b, on=.(a)] # test2
}})

E estes são ambientes:

docker run -it --rm r-base:3.4.0
install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.10.4-3.tar.gz", repos=NULL)
test1
   user  system elapsed 
  0.949   0.007   0.957 
test2
   user  system elapsed 
  0.864   0.000   0.864 
docker run -it --rm r-base:3.6.1
install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.12.2.tar.gz", repos=NULL)
test1
   user  system elapsed 
  2.598   0.047   1.350 
test2
   user  system elapsed 
  2.092   0.016   1.062 



md5-e82041eef8382e88332d077bb608b87c



docker run -it --rm r-base:3.6.1
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
test1
   user  system elapsed 
  1.174   0.045   1.219 
test2
   user  system elapsed 
  0.981   0.024   1.004 

Olá, estou no Windows

Em sex, 26 de junho de 2020, 13:19 Jan Gorecki, [email protected] escreveu:

Verifiquei se #4440 https://github.com/Rdatatable/data.table/pull/4440
resolver esse problema, mas parece que não. Embora horários que eu estou recebendo
aqui são bem diferentes dos horários relatados por @vk111
https://github.com/vk111 , portanto, se você puder testar o desenvolvimento recente
versão e veja se isso faz alguma diferença para o seu fluxo de trabalho que seria
útil.
Este é o script comum que executo em cada ambiente:

biblioteca(data.table)
setDTthreads(2) ## vk111 tem 4 coresaa = data.table(a = seq(1.100), b = rep(0, 100))[, a1 := as.character(a)]bb = data.table(a = seq(1.100), b = rep(1, 100))[, a1 := as.caractere(a)]
setindex(aa,a); setindex(bb, a)
cat("teste1n")
system.time({for(i in c(1:1000))) {
aa[bb, b := ib, on=.(a, a1)] # teste1
}})
cat("teste2n")
system.time({for(i in c(1:1000))) {
aa[bb, b := ib, on=.(a)] # teste2
}})

E estes são ambientes:

docker run -it --rm r- base:3.4.0
install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.10.4-3.tar.gz", repos=NULL)
teste1
sistema do usuário decorrido
0,949 0,007 0,957
teste2
sistema do usuário decorrido
0,864 0,000 0,864

docker run -it --rm r- base:3.6.1
install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.12.2.tar.gz", repos=NULL)
teste1
sistema do usuário decorrido
2,598 0,047 1,350
teste2
sistema do usuário decorrido
2,092 0,016 1,062

docker run -it --rm r- base:3.6.1
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
teste1
sistema do usuário decorrido
1,174 0,045 1,219
teste2
sistema do usuário decorrido
0,981 0,024 1,004

Como você está no Windows, há outro PR pendente que pode eventualmente
ajuda #4558 https://github.com/Rdatatable/data.table/pull/4558 .


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650126662 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MJLU3XRN5YN37ZVLALRYR727ANCNFSM4I4ZPREA
.

@ vk111 Sim, exatamente o que eu estava perguntando. Se você pudesse verificar essas 3 configurações em sua máquina Windows e ver se há algum progresso para você.

Mas como eu entendi pr para Windows ainda não está mesclado

Em sex, 26 de junho de 2020, 20:07 Jan Gorecki, [email protected] escreveu:

@vk111 https://github.com/vk111 Sim, exatamente o que eu estava perguntando.
Se você pudesse verificar essas 3 configurações em sua máquina Windows e ver
se houver algum progresso para você.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650320224 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MMDOCNAWARCCDRSU23RYTPVFANCNFSM4I4ZPREA
.

4440 já está mesclado e ajuda para todos os sistemas operacionais. #4558 ainda está pendente para mesclar.

@vk111 #4558 também já foi mesclado

Olá Jan, segui seu conselho recentemente - #4419
https://github.com/Rdatatable/data.table/issues/4419 relacionado ao meu problema
então eu não tenho esse pedaço exato de código com as junções de caracteres
Mas de qualquer forma obrigado por esta melhoria tenho certeza que vai ajudar muito
pessoas no futuro, se você acredita que tem o melhor desempenho, então eu
acho que você deve apenas mesclá-lo
Obrigada

пт, 26 июн. 2020 г. 20:29, Jan Gorecki [email protected] :

4440 https://github.com/Rdatatable/data.table/pull/4440 já está

mesclados e ajuda para cada sistema operacional. #4558
https://github.com/Rdatatable/data.table/pull/4558 ainda está pendente para
mesclar.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650330154 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MIN2P7BXMKG74Z7EKTRYTSIJANCNFSM4I4ZPREA
.

--
Atenciosamente,
Vasily Kuznetsov

@vk111 os PRs mencionados já estão mesclados. O importante é saber se esse problema foi resolvido, ou pelo menos melhorado. Esses PRs mesclados não estavam tentando resolver esse problema, mas estão relacionados e podem ter sido úteis.

Acontece que o exemplo mínimo inicialmente relatado estava expondo mal o problema. Com base no @vk111 https://github.com/Rdatatable/data.table/issues/3928#issuecomment -538681316 eu construí um exemplo que mostra claramente que há um problema aqui.

install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.10.4-3.tar.gz", repos=NULL)
install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.12.2.tar.gz", repos=NULL)
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
library(data.table)
setDTthreads(2L)
set.seed(108)
n2 = 1:366000
n1 = sample(n2, 30000)
d1=data.table(id1=paste0("id",sample(n1)), id2=paste0("id",sample(n1)), v1=n1)
d2=data.table(id1=paste0("id",sample(n2)), id2=paste0("id",sample(n2)), v2=n2)
system.time(d2[d1, v1 := i.v1, on=c("id1","id2")])



md5-e82041eef8382e88332d077bb608b87c



# 3.4.0: 1.10.4-3
   user  system elapsed 
  0.144   0.000   0.144 
# 3.4.0: 1.12.2
   user  system elapsed 
  0.611   0.003   0.451 
# 3.4.0: 1.12.9
   user  system elapsed 
  0.611   0.000   0.452 



md5-e82041eef8382e88332d077bb608b87c



# 4.0.0: 1.10.4-3
   user  system elapsed 
  0.203   0.008   0.211 
# 4.0.0: 1.12.9
   user  system elapsed 
  0.812   0.004   0.644 

verbose mostra que a maior parte do tempo é gasto Calculated ad hoc index in 0.611s elapsed (0.769s cpu) , que é chamada para forderv de bmerge .

Sim, exatamente
Mas parece que não há melhora nestes testes?

Em ter, 30 de junho de 2020, 00:45 Jan Gorecki, [email protected] escreveu:

Acontece que o exemplo mínimo inicialmente relatado foi mal expondo
o problema. Baseado no @vk111 https://github.com/vk111 #3928 (comentário)
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-538681316
Eu construí um exemplo que mostra claramente que há um problema aqui.

biblioteca(data.table)
setDTthreads(2L)
set.seed(108)n2 = 1:366000n1 = sample(n2, 30000)d1=data.table(id1=paste0("id",sample(n1)), id2=paste0("id",sample(n1) ), v1=n1)d2=data.table(id1=paste0("id",sample(n2)), id2=paste0("id",sample(n2)), v2=n2)
system.time(d2[d1, v1 := i.v1, on=c("id1","id2")])

3.4.0: 1.10.4-3

sistema do usuário decorrido
0,144 0,000 0,144

3.4.0: 1.12.2

sistema do usuário decorrido
0,611 0,003 0,451

3.4.0: 1.12.9

sistema do usuário decorrido
0,611 0,000 0,452

4.0.0: 1.12.9

sistema do usuário decorrido
0,812 0,004 0,644


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-651408089 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/ABRM7MPQHSOEGLXS625BU3TRZEKSBANCNFSM4I4ZPREA
.

Nenhuma melhoria, isso ainda é um problema.
Depois de algumas escavações, descobri que o gargalo é esta chamada
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L282
indo além...
este loop é responsável por 60%
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L242 -L245
e os de 30%
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L252 -L258

Eu tentei verificar se o uso de componentes internos do R ( CHAR() uma macro em vez de uma função) ajudaria aqui, mas não ajuda.


Exemplo ainda mais mínimo, cronometrando apenas forderv , apenas no R 4.0

install.packages("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.10.4-3.tar.gz", repos=NULL)
library(data.table)
setDTthreads(1L)
set.seed(108)
n2 = 1:366000
d2=data.table(id1=paste0("id",sample(n2)), id2=paste0("id",sample(n2)), v2=n2)
system.time(data.table:::forderv(d2, c("id1","id2")))
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
library(data.table)
setDTthreads(1L)
set.seed(108)
n2 = 1:366000
d2=data.table(id1=paste0("id",sample(n2)), id2=paste0("id",sample(n2)), v2=n2)
system.time(data.table:::forderv(d2, c("id1","id2")))



md5-e82041eef8382e88332d077bb608b87c



# 4.0.2: 1.10.4-3
   user  system elapsed 
  0.198   0.000   0.198 
# 4.0.2: 1.12.9
   user  system elapsed 
  0.393   0.000   0.392 

Eu tentei verificar se o uso de componentes internos do R (CHAR() uma macro em vez de uma função) ajudaria aqui, mas não ajuda.

Isso porque R não faz mais isso. Com USE_RINTERNAIS, INTEGER, REAL e presumo CHAR também, ainda são funções inline. Em outras palavras, o benefício (ou seja, macro em vez de função) de USE_RINTERNAL foi removido em versões recentes do R para permitir ALTREP. Eu não acredito que é realmente se é macro ou função ou função inline, por si só, que faz a diferença. É o que está sendo feito por R dentro dessa unidade de trabalho. Antigamente, USE_RINTERNALS tornava uma macro e era uma pesquisa direta de memória (uma desreferência de array apenas levando em consideração o cabeçalho do vetor) e por isso era mais rápido. Era uma unidade de trabalho muito leve. Atualmente, R tem pelo menos uma ramificação para verificar ALTREP e, mesmo com previsão de ramificação, esse trabalho extra aumenta e/ou impede a pré-busca. Em outras palavras, R agora tem um pouco mais de código dentro dessas funções inline. Eu não tenho nenhuma evidência de referência, apenas teoria baseada em olhar para ela.

A causa raiz pode ser a remoção do seguinte branch em cradix_r
https://github.com/Rdatatable/data.table/blob/76bb569fd7736b5f89471a35357e6a971ae1d424/src/forder.c#L780 -L783
e agora para entrada de comprimento 2 não há curto-circuito.
Não é óbvio como colocar essa ramificação agora porque a função mudou muito em termos de como ela opera.

Esta página foi útil?
0 / 5 - 0 avaliações