Data.table: shift() dans data.table v1.9.6 est lent pour de nombreux groupes

Créé le 11 févr. 2016  ·  3Commentaires  ·  Source: Rdatatable/data.table

Salut!
Pour de nombreux groupes différents dans by , shift est beaucoup plus lent que le changement de vitesse manuel.
Voir : http://stackoverflow.com/questions/35179911/shift-in-data-table-v1-9-6-is-slow-for-many-groups
et https://github.com/nachti/datatable_test/blob/master/leadtest.R pour un exemple détaillé.
Acclamations,
Gerhard

GForce performance

Commentaire le plus utile

@ ben519 Pour info , pour le cas particulier où votre code ressemble à ça, il y a un raccourci :

library(data.table)
dt <- data.table(Grp = rep(seq_len(1e6), each=10L))
dt[, Value := sample(100L, size = .N, replace = TRUE)]

system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp][])
#    user  system elapsed 
#   19.50    0.80   20.34
system.time(dt[, v := shift(Value, type = "lag")][rowid(Grp)==1L, v := NA][])
#    user  system elapsed 
#    1.00    0.87    1.25 

dt[, all.equal(v, PrevValueByGrp)]
# [1] TRUE

Tous les 3 commentaires

Ce n'est pas surprenant. Cela disparaîtra lorsque gforce sera optimisé pour := . C'est sur la liste pour cette version, je crois.

+1 pour cette amélioration des performances. shift() est le principal goulot d'étranglement dans une grande partie de mon code. Il semble que pour un nombre fixe de lignes, le temps d'exécution de shift() soit proportionnel au nombre de groupes dans les données.

library(data.table)

# Build table to store timings
timings <- CJ(RowCount = 10^7, Groups = 10^c(0:7))
timings[, SizePerGroup := RowCount/Groups]

# Loop through each experiment
for(i in 1:nrow(dt)){
  print(paste0("Iteration: ", i))

  # Build dataset
  timings_i <- timings[i]
  dt <- data.table(Grp = rep(seq_len(timings_i$Groups), each = timings_i$SizePerGroup))
  dt[, Value := sample(100, size = .N, replace = T)]

  # Measure the time it takes to insert a column indicating the previous value by group
  elapsed <- system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp])["elapsed"]
  timings[i, Elapsed := elapsed]
}

library(ggplot2)
ggplot(timings, aes(x = Groups, y = Elapsed))+geom_line()+geom_point()

screen shot 2018-11-10 at 1 08 15 pm

@ ben519 Pour info , pour le cas particulier où votre code ressemble à ça, il y a un raccourci :

library(data.table)
dt <- data.table(Grp = rep(seq_len(1e6), each=10L))
dt[, Value := sample(100L, size = .N, replace = TRUE)]

system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp][])
#    user  system elapsed 
#   19.50    0.80   20.34
system.time(dt[, v := shift(Value, type = "lag")][rowid(Grp)==1L, v := NA][])
#    user  system elapsed 
#    1.00    0.87    1.25 

dt[, all.equal(v, PrevValueByGrp)]
# [1] TRUE
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

st-pasha picture st-pasha  ·  3Commentaires

tcederquist picture tcederquist  ·  3Commentaires

rafapereirabr picture rafapereirabr  ·  3Commentaires

DavidArenburg picture DavidArenburg  ·  3Commentaires

arunsrinivasan picture arunsrinivasan  ·  3Commentaires