Data.table: unir la operación casi 2 veces más lento

Creado en 2 oct. 2019  ·  29Comentarios  ·  Fuente: Rdatatable/data.table

hola estaba probando
data.table_1.10.4-3 + R versión 3.4.0 (2017-04-21)
contra
data.table_1.12.2 + R versión 3.6.1 (2019-07-05)

y he notado que la operación de unión es casi 2 veces más lenta en la nueva versión data.table (R?)
Creo que depende principalmente de la versión de 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 comentarios

Ha ejecutado lo siguiente:

# 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)

Luego hizo lo siguiente para crear esta trama.

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
}]


Después de comenzar, me di cuenta de que podía simplificar esto un poco 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 agregar el tiempo de compromiso directamente al punto de referencia

unirse_timings.txt

Hola MichaelChirico, he leído dos veces
pero, ¿qué significa exactamente la línea de tiempo de 2016 a 2019? ¿Es una versión de datatable?

no solo versiones sino confirmaciones específicas. déjame probar y agregar algo de demarcación de versiones, una buena idea que olvidé agregar

@MichaelChirico, su gráfico se ve genial, lo que faltaba era una interpretación de eso :) Al adivinar, diría que el nuevo ford paralelo es más lento para una entrada de longitud 100 que antes. Lo cual, en mi opinión, está bien, porque todavía son microsegundos. Por supuesto, vale la pena reducir los gastos generales, pero la prioridad debe ser una reducción de los recursos en los escenarios de uso más comunes. Repetir 10000 veces en una entrada de longitud 100 definitivamente no es uno de esos.

esa fue mi suposición también después de mirar las NOTICIAS 1.12.0. intentará volver a ejecutar un solo subproceso.

@jangorecki , si haces las matemáticas simples, son miles de microsegundos, es decir, milisegundos
La inspiración de esta prueba fue mi proyecto actual donde uno 7-8 tablas de multiplicar con 40 000 filas
Antes tarda 18 segundos, después tarda 40 segundos
Mi prueba también incluye clave de carácter
Instalé 3.6+1.12 y luego lo revertí a 3.4+1.10
Creo que esta no es una situación normal, es por eso que este problema está aquí.

Sí, el gráfico es realmente impresionante; deberíamos hacer más de esto y automatizarlo.

Pero el informe original compara R 3.4 con R 3.6, que tiene R 3.5 en el medio. Sabemos que R 3.5 afectó data.table a través del cambio de ALTREP de REAL(), INTEGER() de macros a funciones (ligeramente más pesadas).

@vk111 ¿Puede volver a ejecutar sus pruebas con v1.12.4 ahora en CRAN? ¿Algo mejor? Hemos estado tomando R API fuera de los bucles para hacer frente a R 3.5+. Como siguiente paso, sería genial saber cómo encuentra v1.12.4. ¿Puede también incluir más información sobre su máquina; por ejemplo, sistema operativo, RAM y número de CPU.

@matt , lo haré

Hola @mattdowle ,

He actualizado a 1.12.4 (+R 3.6.1) - básicamente hay los mismos números para la prueba unitaria y mi func
Consideraré aquí solo las uniones con carácter sin indexación, como punto de referencia
Prueba unitaria (como se mencionó en la primera publicación)
3.6.1: 6,87 seg sin índice
3.4.0: 3,02 segundos (sin índice)

Mi función del proyecto sigue siendo la misma: 20 vs 40 segundos
Consiste solo en ~14 uniones dt
dos tablas 30 000 filas (dt1) y 366 000 filas (dt2)
15 columnas cada uno
la clave es de 2 caracteres y 1 numérico
y asignó 7 campos (de dt1 a dt2) durante la unión

mi PC:
ganar 10 64 bits
AMD A8 2.2GHz
RAM de 8GB

cmd: wmic cpu obtener NumberOfCores, NumberOfLogicalProcessors/ Format:List
Número de núcleos = 4
NúmeroDeProcesadoresLógicos=4

gracias por tu analisis

Hola @mattdowle , ¿estás considerando esto?

Según un git bisect que acabo de volver a ejecutar, esta confirmación es "culpable" de la ralentización, con suerte eso puede ayudar a Matt a identificar la raíz. Que esté relacionado con forder me hace estar relativamente seguro de que lo hemos identificado correctamente.

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

Más 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)

Con estos dos scripts, desde master/HEAD :

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

Luego, en cada iteración, ejecute sh run_join_time.sh y verifique el resultado. Las confirmaciones bad tardaban aproximadamente 0,9 segundos por iteración en mi máquina, las confirmaciones de good aproximadamente 0,7.

Hola Michael, gracias, pero el rendimiento se ha reducido drásticamente, especialmente
para la clave de carácter: proporcioné la prueba unitaria en la primera publicación
De todos modos, creo que debemos esperar la confirmación de Matt si está arreglado en
nueva versión o no

El jueves 26 de diciembre de 2019 a las 15:02, Michael Chirico [email protected]
escribió:

De acuerdo con una bisección de git que acabo de volver a ejecutar, este compromiso es "culpable" para el
Reduzca la velocidad, con suerte eso puede ayudar a Matt a identificar la raíz. que es
relacionado con forder me hace relativamente seguro de que lo hemos precisado
correctamente.

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

Más precisamente:

run_join_time.sh

R CMD INSTALACIÓN. && Rscript time_join.R

time_join.R

biblioteca (tabla de datos)
biblioteca (microbenchmark)

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

resumen(microbenchmark(veces = 1000L, aa[bb, b := ib, on=.(a)])$tiempo/1e6)

Con estos dos scripts, de master/HEAD:

pago git 1.12.0
git bisect inicio
bisecar mal
git bisect bien 1.11.8

Luego, en cada iteración, ejecute sh run_join_time.sh y verifique el resultado. El
las confirmaciones incorrectas tardaban aproximadamente 0,9 segundos por iteración en mi máquina,
buenas confirmaciones sobre .7.


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MJQITNUZDNYV7NTIX3Q2S2ORA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHVTR4Q#issue,0636669
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MOTZRFFM2QKVFUHT6LQ2S2ORANCNFSM4I4ZPREA
.

>

Atentamente,
Vasili Kuznetsov

@vk111 si este problema no está cerrado, entonces puede asumir con seguridad que el problema aún no está solucionado. Cada vez que arreglamos algo, cerramos el problema relacionado.

@vk111 es posible que pueda mitigar con algunos ajustes menores usando setkey en lugar de setindex . Esto reduce su prueba a más de la mitad en mi computadora:

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)
  )
)

Hola Cole, sí, sé sobre setkey: proporcioné arriba la breve descripción
de mi proyecto y no hay propósito de 1000 uniones - hay como 10-20
se une y la cosa es que mis cadenas de caracteres son muy dinámicas y yo
necesita hacer setkey cada vez antes de unirse como 20 veces setkey y 20
veces se une y por lo tanto la ganancia en el tiempo es menor que 2 veces
Vivo con 3.4.0 por un tiempo como una solución general para esta situación
y probablemente no sea gran cosa arreglarlo en una nueva versión, especialmente si
hay un cometer culpable encontrado
Por cierto, si comparamos manzanas con manzanas, creo que 3.4(1.10) será
aún más rápido que 3.6 (1.12) si uso la misma prueba unitaria con la tecla set para
ambas versiones
Felices vacaciones

El domingo 29 de diciembre de 2019 a las 14:48 Cole Miller, [email protected] escribió:

@vk111 https://github.com/vk111 es posible que pueda mitigar con algunos
ajustes menores usando setkey en lugar de setindex. Esto reduce su prueba por
más de la mitad en mi computadora:

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

aa[, a1 := como.personaje(a)]
bb[, a1 := como.personaje(a)]

tic()
para(yo en c(1:1000)) {
aa[bb, b := ib, on=.(a, a1)] # test1 sin clave
}
toc()

4 segundos transcurridos

tic()
establecer clave (aa, a, a1)
tecla de ajuste (bb, a, a1)

para(yo en c(1:1000)) {
aa[bb, b := ib] # test2 sin clave
}
toc()

1,46 segundos transcurridos

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

biblioteca (microbenchmark)
biblioteca (tabla de datos)

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

aa[, a1 := como.personaje(a)]
bb[, a1 := como.personaje(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(copia(aa), a, a1)
bb_int_char = setkey(copiar(bb), a, a1)
toc()
int_nokey = función (dt1, dt2) {
dt1[dt2, b := ib, on=.(a)]
}

int_key = función (dt1, dt2) {
dt1[dt2, b := ib]
}

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

int_char_key = función (dt1, dt2) {
dt1[dt2, b := ib]
}

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

diagrama de caja(
micropunto de referencia(
a_no_key = int_nokey(aa, bb),
a_clave = int_clave(aa_int_clave, bb_int_clave),
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)
)
)


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MPU64YBK7UNT3O3OYDQ3CTBRA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHY73VA#issuecomment-5
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MKSP6LCUJD2HOAG7D3Q3CTBRANCNFSM4I4ZPREA
.

Hay un PR #4370 pendiente que está relacionado. Puede unirse con menos gastos generales que [ normalmente impone. Reduce el tiempo de su ejemplo por un factor de 2. Cuanto más grandes son los datos, menor es la mejora, pero por otro lado, cuantas más iteraciones, mejor mejora. Tenga en cuenta que no hay forma de actualizar la columna durante la unión. Básicamente, debe agregar columnas durante la unión y luego usar algo como fcoalesce , pero eso debería funcionar.
Debería obtener algo de velocidad adicional una vez que #4386 también se fusione.

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 fusión #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

hola jan ok gracias

Cuanto más grandes son los datos, menor es la mejora, pero por otro lado,
cuantas más iteraciones, mejor mejora
El problema real está relacionado con los grandes datos y algunas iteraciones: lo escribí
sobre

El lunes 4 de mayo de 2020 a las 00:33 de enero Gorecki, [email protected] escribió:

Hay un PR #4370 pendiente
https://github.com/Rdatatable/data.table/pull/4370 que está relacionado. Eso
puede hacer una unión con menos gastos generales que [ impone normalmente. reduce el
tiempo de su ejemplo por un factor de 2. Cuanto mayor sea la información, menor
la mejora, pero por otro lado, cuantas más iteraciones, mejor
mejora. Tenga en cuenta que no hay forma de actualizar la columna durante la unión. Ustedes
básicamente tiene que agregar columnas durante la unión, y luego usar algo como
fcoalesce, pero eso debería ser eficaz.
Debería obtener algo de velocidad extra una vez #4386
https://github.com/Rdatatable/data.table/pull/4386 también se fusionará.

biblioteca(datos.tabla)aa = datos.tabla(a = seq(1,100), b = rep(0, 100))bb = datos.tabla(a = seq(1,100), b = rep(1, 100))
setindex(aa, a)
setindex(bb, a)p = proc.time()[[3L]]for (i en c(1:1000)) {
aa[bb, b := ib, on=.(a)]
}
tiempo de proceso()[[3L]]-p#[1] 1.1

lista de combinación #4370 https://github.com/Rdatatable/data.table/pull/4370

biblioteca(datos.tabla)aa = datos.tabla(a = seq(1,100), b = rep(0, 100))bb = datos.tabla(a = seq(1,100), b = rep(1, 100))
setindex(aa, a)
setindex(bb, a)p = proc.time()[[3L]]for (i en c(1:1000)) {
mergelist(lista(aa, bb), on="a")
}
tiempo de proceso()[[3L]]-p#[1] 0.696


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-623193573 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MJR5THRHE3FIXXV3YTRPXWNNANNCNFSM4I4ZPREA
.

Verifiqué si #4440 (fusionado ayer) resuelve este problema, pero parece que no. Aunque los tiempos que obtengo aquí son bastante diferentes de los tiempos informados por @vk111 , por lo que sería útil si puede probar la versión de desarrollo reciente y ver si hace alguna diferencia para su flujo de trabajo.
Como está en Windows, hay otro PR pendiente que eventualmente podría ayudar #4558.


Este es el script común que ejecuto en cada entorno:

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
}})

Y estos son los 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 

hola estoy en windows

El viernes, 26 de junio de 2020, 13:19 de enero, Gorecki, [email protected] escribió:

Verifiqué si # 4440 https://github.com/Rdatatable/data.table/pull/4440
resolver este problema, pero parece que no lo hizo. Aunque los tiempos que estoy recibiendo
aquí son bastante diferentes de los tiempos informados por @vk111
https://github.com/vk111 , por lo que si puede probar el desarrollo reciente
versión, y vea si hace alguna diferencia para su flujo de trabajo que sería
servicial.
Este es el script común que ejecuto en cada entorno:

biblioteca (tabla de datos)
setDTthreads(2) ## vk111 tiene 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 := como.personaje(a)]
setindex(aa, a); setindex(bb, a)
gato("prueba1n")
system.time({para(i en c(1:1000)) {
aa[bb, b := ib, on=.(a, a1)] # prueba1
}})
gato("prueba2n")
system.time({para(i en c(1:1000)) {
aa[bb, b := ib, on=.(a)] # prueba2
}})

Y estos son los ambientes:

ventana acoplable ejecutar -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)
prueba1
sistema de usuario transcurrido
0,949 0,007 0,957
prueba2
sistema de usuario transcurrido
0,864 0,000 0,864

ventana acoplable ejecutar -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)
prueba1
sistema de usuario transcurrido
2.598 0.047 1.350
prueba2
sistema de usuario transcurrido
2.092 0.016 1.062

ventana acoplable ejecutar -it --rm r- base:3.6.1
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
prueba1
sistema de usuario transcurrido
1.174 0.045 1.219
prueba2
sistema de usuario transcurrido
0,981 0,024 1,004

Como estás en Windows, hay otro PR pendiente que eventualmente podría
ayuda #4558 https://github.com/Rdatatable/data.table/pull/4558 .


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650126662 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MJLU3XRN5YN37ZVLALRYR727ANCNFSM4I4ZPREA
.

@ vk111 Sí, exactamente lo que estaba preguntando. Si pudiera verificar esas 3 configuraciones en su máquina con Windows y ver si hay algún progreso para usted.

Pero como entendí, pr para Windows aún no está fusionado

El viernes, 26 de junio de 2020 a las 20:07, enero Gorecki, [email protected] escribió:

@vk111 https://github.com/vk111 Sí, exactamente lo que estaba preguntando.
Si pudiera verificar esas 3 configuraciones en su máquina con Windows y ver
si hay algún progreso para usted.


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650320224 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MMDOCNAWARCCDRSU23RYTPVFANCNFSM4I4ZPREA
.

4440 ya está combinado y es compatible con todos los sistemas operativos. #4558 aún está pendiente de fusionarse.

@vk111 #4558 ya se ha fusionado también

Hola Jan, seguí tu consejo recientemente - #4419
https://github.com/Rdatatable/data.table/issues/4419 relacionado con mi problema
así que no tengo este código exacto con las uniones de caracteres
Pero de todos modos, gracias por esta mejora, estoy seguro de que ayudará mucho a
gente en el futuro si crees que tiene el mejor rendimiento entonces yo
supongo que deberías fusionarlo
Gracias

пт, 26 июн. 2020 g. a las 20:29, enero Gorecki [email protected] :

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

combinado y ayuda para cada sistema operativo. #4558
https://github.com/Rdatatable/data.table/pull/4558 aún está pendiente de
unir.


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650330154 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MIN2P7BXMKG74Z7EKTRYTSIJANCNFSM4I4ZPREA
.

--
Atentamente,
Vasili Kuznetsov

@vk111 Los PR mencionados ya están fusionados. La cuestión es saber si este tema se resolvió, o al menos mejoró. Esos RP fusionados no intentaban resolver este problema, pero están relacionados, por lo que podrían haber sido útiles.

Sucede que el ejemplo mínimo informado inicialmente estaba exponiendo mal el problema. Basado en @vk111 https://github.com/Rdatatable/data.table/issues/3928#issuecomment -538681316, construí un ejemplo que muestra claramente que hay un problema aquí.

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 muestra que la mayor parte del tiempo se gasta Calculated ad hoc index in 0.611s elapsed (0.769s cpu) , que es llamar a forderv desde bmerge .

Sí exactamente
¿Pero parece que no hay mejora en estas pruebas?

El martes, 30 de junio de 2020 a las 00:45, enero Gorecki, [email protected] escribió:

Sucede que el ejemplo mínimo informado inicialmente exponía mal
la cuestión. Basado en @vk111 https://github.com/vk111 #3928 (comentario)
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-538681316
Construí un ejemplo que muestra claramente que hay un problema aquí.

biblioteca (tabla de datos)
establecer hilos DT (2L)
set.seed(108)n2 = 1:366000n1 = muestra(n2, 30000)d1=datos.tabla(id1=pegar0("id",muestra(n1)), id2=pegar0("id",muestra(n1) ), v1=n1)d2=data.table(id1=pegar0("id",muestra(n2)), id2=pegar0("id",muestra(n2)), v2=n2)
system.time(d2[d1, v1 := i.v1, on=c("id1","id2")])

3.4.0: 1.10.4-3

sistema de usuario transcurrido
0,144 0,000 0,144

3.4.0: 1.12.2

sistema de usuario transcurrido
0,611 0,003 0,451

3.4.0: 1.12.9

sistema de usuario transcurrido
0,611 0,000 0,452

4.0.0: 1.12.9

sistema de usuario transcurrido
0,812 0,004 0,644


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-651408089 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/ABRM7MPQHSOEGLXS625BU3TRZEKSBANCNFSM4I4ZPREA
.

Sin mejoras, esto sigue siendo un problema.
Después de investigar un poco, encontré que el cuello de botella es esta llamada
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L282
ir más lejos...
este bucle es responsable del 60%
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L242 -L245
y los del 30%
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L252 -L258

Intenté verificar si usar las funciones internas de R ( CHAR() una macro en lugar de una función) ayudaría aquí, pero no ayuda.


Ejemplo aún más mínimo, sincronización forderv solo, solo en 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 

Intenté verificar si usar R internals (CHAR() una macro en lugar de una función) ayudaría aquí, pero no ayuda.

Eso es porque R ya no hace eso. Con USE_RINTERNALS, INTEGER, REAL y supongo que CHAR también siguen siendo funciones en línea. En otras palabras, el beneficio (es decir, macro en lugar de función) de USE_RINTERNALS se eliminó en versiones recientes de R para permitir ALTREP. No creo que sea realmente si se trata de una macro, una función o una función en línea, per se, lo que marca la diferencia. Es lo que está haciendo R dentro de esa unidad de trabajo. En los viejos tiempos, USE_RINTERNALS lo convertía en una macro y era una búsqueda directa en la memoria (una desreferencia de matriz que solo tenía en cuenta el encabezado del vector), por lo que era más rápido. Era una unidad de trabajo muy ligera. En estos días, R tiene al menos una rama para verificar ALTREP e, incluso con la predicción de ramas, ese trabajo adicional se suma y/o evita la captación previa. En otras palabras, R ahora tiene un poco más de código dentro de estas funciones en línea. No tengo evidencia de referencia, solo teoría basada en mirarla.

La causa raíz podría ser la eliminación de la siguiente rama en cradix_r
https://github.com/Rdatatable/data.table/blob/76bb569fd7736b5f89471a35357e6a971ae1d424/src/forder.c#L780 -L783
y ahora para la entrada de longitud 2 no hay cortocircuito.
No es obvio cómo poner esa rama ahora porque la función ha cambiado mucho en términos de cómo opera.

¿Fue útil esta página
0 / 5 - 0 calificaciones