Data.table: الانضمام إلى العملية أبطأ مرتين تقريبًا

تم إنشاؤها على ٢ أكتوبر ٢٠١٩  ·  29تعليقات  ·  مصدر: Rdatatable/data.table

مرحبًا ، كنت أختبر
data.table_1.10.4-3 + R الإصدار 3.4.0 (2017-04-21)
ضد
data.table_1.12.2 + R الإصدار 3.6.1 (2019-07-05)

ولاحظت أن عملية الانضمام أبطأ مرتين تقريبًا في الإصدار الجديد من data.table (R؟)
أعتقد أنه يعتمد في الغالب على إصدار جدول البيانات

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

ال 29 كومينتر

قم بتشغيل ما يلي:

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

ثم قم بما يلي لإنشاء هذه المؤامرة

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


بعد البدء أدركت أنه يمكنني تبسيط هذا قليلاً باستخدام

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)

لإضافة وقت الالتزام مباشرة إلى المعيار

Join_timings.txt

مرحباً MichaelChirico ، لقد قرأت مرتين
ولكن ماذا يعني بالضبط الجدول الزمني من 2016 إلى 2019؟ هل هي نسخة من جدول البيانات؟

ليس فقط الإصدارات ولكن التزامات محددة. اسمحوا لي أن أحاول إضافة بعض ترسيم الإصدارات ، وهي فكرة جيدة نسيت إضافتها

MichaelChirico الرسم البياني الخاص بك يبدو رائعًا للغاية ، ما كان مفقودًا هو تفسير لذلك :) من خلال التخمين ، سأقول أن forder الموازي الجديد أبطأ لإدخال بطول 100 مما كان عليه من قبل. أي IMO جيد ، لأن هذه لا تزال ميكروثانية. من المفيد بالطبع تقليل النفقات العامة ولكن يجب أن تكون الأولوية هي تقليل الموارد في سيناريوهات الاستخدام الأكثر شيوعًا. تكرار 10000 مرة بطول 100 إدخال ليس بالتأكيد واحدًا من هؤلاء.

كان هذا تخميني أيضًا بعد النظر إلى أخبار 1.12.0. سيحاول إعادة تشغيل مترابطة واحدة.

jangorecki ، إذا أجريت العمليات الحسابية البسيطة ، فستحصل على آلاف الميكروثانية ، أي ميلي ثانية
كان مصدر إلهام هذا الاختبار هو مشروعي الحالي حيث انضممت إلى جداول ضرب 7-8 مع 40000 صف
قبل أن تستغرق 18 ثانية ، بعد أن تستغرق 40 ثانية
يتضمن اختباري أيضًا مفتاح الحرف
لقد قمت بتثبيت 3.6 + 1.12 ثم قمت بإعادته مرة أخرى إلى 3.4 + 1.10
أعتقد أن هذا ليس وضعًا طبيعيًا ولهذا السبب هذه المشكلة هنا

نعم الرسم البياني رائع حقًا ؛ يجب أن نفعل المزيد من هذا وأتمته.

لكن التقرير الأصلي يقارن بين 3.4 راند و 3.6 راند ، و 3.5 راند في المنتصف. نعلم أن البيانات المتأثرة R 3.5 هي جدول من خلال تغيير ALTREP للوظائف REAL () و INTEGER () من وحدات الماكرو إلى وظائف (أثقل قليلاً).

@ vk111 هل يمكنك من فضلك إعادة اختباراتك مع v1.12.4 الآن على CRAN. أي تحسن؟ لقد أخذنا حلقات R API الخارجية للتعامل مع R 3.5+. كخطوة تالية ، سيكون من الرائع معرفة كيفية العثور على الإصدار 1.12.4. هل يمكنك أيضًا تضمين مزيد من المعلومات حول جهازك ؛ مثل نظام التشغيل وذاكرة الوصول العشوائي وعدد وحدة المعالجة المركزية.

matt ، سوف تفعل

مرحبًا mattdowle ،

لقد تم التحديث إلى 1.12.4 (+ R 3.6.1) - يوجد أساسًا نفس الأرقام لاختبار الوحدة ووظيفتي
سأفكر هنا فقط في الانضمام مع الطابع دون فهرسة - كمعيار
اختبار الوحدة (كما هو مذكور في التدوينة الأولى)
3.6.1: 6.87 ثانية بدون فهرس
3.4.0: 3.02 ثانية (بدون فهرس)

تظل وظيفتي من المشروع كما هي: 20 مقابل 40 ثانية
يتكون فقط من صلات 14 دينارًا تقريبًا
جدولين 30000 صف (dt1) و 366000 صف (dt2)
15 عمودًا لكل منهما
المفتاح يتكون من حرفين ورقم واحد
وتعيين 7 حقول (من dt1 إلى dt2) أثناء الربط

جهاز الكمبيوتر الخاص بي:
فوز 10 64 بت
AMD A8 2.2 جيجاهرتز
8 جيجا بايت رام

cmd: وحدة المعالجة المركزية wmic الحصول على NumberOfCores و NumberOfLogicalProcessors / Format: List
NumberOfCores = 4
NumberOfLogicalProcessors = 4

شكرا لك على تحليلك

مرحبًا mattdowle فهل تفكر في ذلك؟

وفقًا لـ git bisect لقد قمت للتو بإعادة التشغيل ، فإن هذا الالتزام "مذنب" بسبب التباطؤ ، ونأمل أن يساعد ذلك Matt في تحديد الجذر. كونه مرتبطًا بـ forder يجعلني واثقًا نسبيًا من أننا قمنا بتثبيته بشكل صحيح.

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

أكثر دقة:

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

باستخدام هذين النصين ، من master/HEAD :

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

ثم في كل تكرار ، قم بتشغيل sh run_join_time.sh وتحقق من النتيجة. كانت الالتزامات bad تستغرق تقريبًا 0.9 ثوانٍ لكل تكرار على جهازي ، و good تلتزم بحوالي .7.

مرحبًا مايكل ، شكرًا لك ، لكن الأداء انخفض بشكل كبير بشكل خاص
لمفتاح الحرف - قدمت مع اختبار الوحدة في أول مشاركة
على أي حال ، أعتقد أننا بحاجة إلى انتظار التأكيد من مات سواء تم إصلاحه في
نسخة جديدة أم لا

يوم الخميس ، 26 ديسمبر 2019 الساعة 15:02 ، Michael Chirico [email protected]
كتب:

وفقًا لبوابة bisect التي أعدتها للتو ، فإن هذا الالتزام "مذنب" لـ
تبطئ ، ونأمل أن يساعد ذلك مات على تحديد الجذر. هذا هو
ذات الصلة بـ forder تجعلني واثقًا نسبيًا من أننا قمنا بتثبيته
بشكل صحيح.

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

أكثر دقة:

run_join_time.sh

R CMD التثبيت. && Rscript time_join.R

time_join.R

مكتبة (جدول البيانات)
مكتبة (microbenchmark)

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

الملخص (العلامات الدقيقة (الأوقات = 1000 لتر ، أأ [ب ب ، ب: = ب ، على =. (أ)]) دولار الوقت / 1e6)

مع هذين النصين ، من Master / HEAD:

بوابة الخروج 1.12.0
بداية git bisect
بوابة المنصف سيئة
بوابة شطر جيدة 1.11.8

ثم في كل تكرار ، قم بتشغيل sh run_join_time.sh وتحقق من النتيجة. ال
كانت الالتزامات السيئة تستغرق حوالي 0.9 ثانية لكل تكرار على جهازي ،
جيدة يرتكب .7.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928؟email_source=notifications&email_token=ABRM7MJQITNUZDNYV7NTIX3Q2S2ORA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VM66
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MOTZRFFM2QKVFUHT6LQ2S2ORANCNFSM4I4ZPREA
.

>

مع أطيب التحيات،
فاسيلي كوزنتسوف

@ vk111 إذا لم يتم إغلاق هذه المشكلة ، فيمكنك أن تفترض بأمان أن المشكلة لم يتم حلها بعد. عندما نصلح شيئًا ما ، نغلق المشكلة ذات الصلة.

@ vk111 ، قد تتمكن من التخفيف من بعض التعديلات الطفيفة باستخدام setkey بدلاً من setindex . يؤدي هذا إلى خفض اختبارك بأكثر من النصف على جهاز الكمبيوتر الخاص بي:

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

مرحبًا كول ، نعم أعرف شيئًا عن setkey - لقد قدمت الوصف المختصر أعلاه
من مشروعي وليس هناك غرض من 1000 انضمام - هناك مثل 10-20
ينضم والشيء هو أن سلاسل شخصيتي ديناميكية للغاية وأنا
تحتاج إلى جعل setkey في كل مرة قبل الانضمام مثل setkey 20 مرة و 20
مرات ينضم ، وبالتالي فإن الربح في الوقت المناسب أقل من مرتين
أعيش مع 3.4.0 لفترة من الوقت كحل عام لهذا الموقف
وربما ليس بالأمر المهم إصلاحه في الإصدار الجديد خاصةً إذا كان
تم العثور على ارتكاب مذنب
بالمناسبة ، إذا قارنا التفاح بالتفاح ، أعتقد أن 3.4 (1.10) سيكون كذلك
لا يزال أسرع من 3.6 (1.12) إذا استخدمت نفس اختبار الوحدة مع setkey لـ
كلا الإصدارين
اجازة سعيدة

في الأحد ، 29 ديسمبر 2019 ، 14:48 كول ميلر ، كتب Cole Miller ، [email protected] :

@ vk111 https://github.com/vk111 قد تتمكن من التخفيف مع البعض
تعديلات طفيفة باستخدام setkey بدلاً من setindex. هذا يقطع الاختبار الخاص بك
أكثر من النصف على جهاز الكمبيوتر الخاص بي:

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

عرة ()
لـ (i in c (1: 1000)) {
aa [bb، b: = ib، on =. (a، a1)] # test1 بدون مفتاح
}
توك ()

انقضت 4 ثوان

عرة ()
setkey (aa، a، a1)
setkey (bb، a، a1)

لـ (i in c (1: 1000)) {
aa [bb، b: = ib] # test2 بدون مفتاح
}
توك ()

انقضت 1.46 ثانية

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

مكتبة (microbenchmark)
مكتبة (جدول البيانات)

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 = نسخ (أأ)
bb_nokey = نسخ (ب ب)

عرة ()
aa_int_key = setkey (نسخة (أأ) ، أ)
bb_int_key = setkey (نسخة (bb) ، أ)
توك ()

عرة ()
aa_int_char = setkey (copy (aa) ، a ، a1)
bb_int_char = setkey (copy (bb)، a، a1)
توك ()
int_nokey = وظيفة (dt1، dt2) {
dt1 [dt2، b: = ib، on =. (a)]
}

int_key = وظيفة (dt1، dt2) {
dt1 [dt2، b: = ib]
}

int_char_nokey = وظيفة (dt1 ، dt2) {
dt1 [dt2، b: = ib، on =. (a، a1)]
}

int_char_key = وظيفة (dt1، dt2) {
dt1 [dt2، b: = ib]
}

int_char_key_on = وظيفة (dt1، dt2) {
dt1 [dt2، b: = ib، on =. (a، a1)]
}

مربع مؤامرة(
علامة القياس الدقيقة (
a_no_key = int_nokey (أأ ، ب ب) ،
a_key = int_key (aa_int_key ، bb_int_key) ،
a_a1_no_key = int_char_nokey (أأ ، ب ب) ،
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)
)
)

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928؟email_source=notifications&email_token=ABRM7MPU64YBK7UNT3O3OYDQ3CTBRA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMV50
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MKSP6LCUJD2HOAG7D3Q3CTBRANCNFSM4I4ZPREA
.

هناك رقم PR # 4370 معلق مرتبط. يمكن أن يجعل الانضمام مع أقل النفقات العامة التي يفرضها [ عادة. إنه يقلل من توقيت المثال الخاص بك بمعامل 2. كلما كانت البيانات أكبر ، كلما كان التحسن أصغر ، ولكن من ناحية أخرى ، كلما زاد عدد التكرارات ، كان التحسين أفضل. لاحظ أنه لا توجد طريقة لتحديث العمود أثناء الانضمام. يجب عليك بشكل أساسي إضافة أعمدة أثناء الانضمام ، ثم استخدام شيء مثل fcoalesce ، لكن يجب أن يكون ذلك جيدًا.
يجب أن تحصل على بعض السرعة الإضافية بمجرد دمج # 4386 أيضًا.

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

قائمة الاندماج # 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

مرحبًا جان ، حسنًا ، شكرًا

كلما زادت البيانات ، قل التحسن ، ولكن من ناحية أخرى ،
كلما زاد عدد التكرارات ، كان التحسين أفضل
تتعلق المشكلة الحقيقية بالبيانات الضخمة وعدد قليل من التكرارات - لقد كتبتها
في الاعلى

في الإثنين ، 4 مايو 2020 ، 00:33 ، كتب جان جوريكي ، [email protected] :

هناك رقم PR # 4370 معلق
https://github.com/Rdatatable/data.table/pull/4370 وهو ذو صلة. هو - هي
يمكن أن تجعل الانضمام مع أقل النفقات العامة التي [تفرض عادة. يقلل من
توقيت المثال الخاص بك بمعامل 2. كلما كبرت البيانات ، كلما قل
التحسن ، ولكن من ناحية أخرى ، كلما زاد عدد التكرارات ، كان ذلك أفضل
تحسين. لاحظ أنه لا توجد طريقة لتحديث العمود أثناء الانضمام. أنت
يجب عليك في الأساس إضافة أعمدة أثناء الانضمام ، ثم استخدام شيء مثل
fcoalesce ، لكن يجب أن يكون ذلك مؤديًا.
يجب أن تحصل على بعض السرعة الإضافية مرة واحدة # 4386
سيتم أيضًا دمج https://github.com/Rdatatable/data.table/pull/4386 .

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 (bb، a) p = proc.time () [[3L]] لـ (i in c (1: 1000)) {
أأ [ب ب ، ب: = ب ، على =. (أ)]
}
proc.time () [[3L]] - p # [1] 1.1

قائمة الاندماج # 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 (bb، a) p = proc.time () [[3L]] لـ (i in c (1: 1000)) {
قائمة الاندماج (القائمة (أأ ، ب ب) ، على = "أ")
}
proc.time () [[3L]] - p # [1] 0.696

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-623193573 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MJR5THRHE3FIXXV3YTRPXWNNANCNFSM4I4ZPREA
.

لقد تحققت مما إذا كان رقم 4440 (تم دمجه بالأمس) يحل هذه المشكلة ، لكنه لا يبدو كذلك. على الرغم من أن التوقيتات التي أحصل عليها هنا مختلفة تمامًا عن التوقيتات التي أبلغ عنها @ vk111 ، لذلك إذا كنت قادرًا على اختبار إصدار التطوير الأخير ، ومعرفة ما إذا كان ذلك سيحدث أي فرق في سير عملك ، فسيكون ذلك مفيدًا.
نظرًا لأنك على Windows ، هناك علاقات عامة أخرى معلقة قد تساعد في النهاية على # 4558.


هذا هو النص الشائع الذي أقوم بتشغيله في كل بيئة:

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

وهذه البيئات:

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 

مرحبًا ، أنا على Windows

في الجمعة ، 26 يونيو 2020 ، الساعة 13:19 ، كتب جان جوريكي ، [email protected] :

لقد تحققت مما إذا كان # 4440 https://github.com/Rdatatable/data.table/pull/4440
حل هذه المشكلة ، ولكن يبدو أنها لم تفعل. على الرغم من أنني أحصل على توقيت
هنا مختلفة تمامًا عن التوقيتات التي أبلغ عنها @ vk111
https://github.com/vk111 ، لذلك إذا كنت قادرًا على اختبار التطوير الحديث
الإصدار ، ومعرفة ما إذا كان سيحدث أي فرق في سير عملك
نافع.
هذا هو النص الشائع الذي أقوم بتشغيله في كل بيئة:

مكتبة (جدول البيانات)
يحتوي setDTthreads (2) ## vk111 على 4 نوى = 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)]
سيتينديكس (أأ ، أ) ؛ سيتينديكس (ب ب ، أ)
قطة ("test1n")
system.time ({for (i in c (1: 1000)) {
aa [bb، b: = ib، on =. (a، a1)] # test1
}})
قطة ("test2n")
system.time ({for (i in c (1: 1000)) {
aa [bb، b: = ib، on =. (a)] # test2
}})

وهذه البيئات:

تشغيل docker -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)
اختبار 1
انقضى نظام المستخدم
0.949 0.007 0.957
اختبار 2
انقضى نظام المستخدم
0.864 0.000 0.864

تشغيل docker -it -rm r- القاعدة: 3.6.1
install.packages ("https://cran.r-project.org/src/contrib/Archive/data.table/data.table_1.12.2.tar.gz" ، repos = NULL)
اختبار 1
انقضى نظام المستخدم
2.598 0.047 1.350
اختبار 2
انقضى نظام المستخدم
2.092 0.016 1.062

تشغيل docker -it -rm r- القاعدة: 3.6.1
install.packages ("data.table" ، repos = "https://Rdatatable.gitlab.io/data.table")
اختبار 1
انقضى نظام المستخدم
1.174 0.045 1.219
اختبار 2
انقضى نظام المستخدم
0.981 0.024 1.004

نظرًا لأنك تستخدم نظام التشغيل Windows ، فهناك علاقات عامة معلقة أخرى يمكن أن تحدث في النهاية
مساعدة # 4558 https://github.com/Rdatatable/data.table/pull/4558 .

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650126662 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MJLU3XRN5YN37ZVLALRYR727ANCNFSM4I4ZPREA
.

@ vk111 نعم ، بالضبط ما كنت أسأل عنه. إذا كان بإمكانك التحقق من هذه الأشكال الثلاثة على جهاز Windows الخاص بك ومعرفة ما إذا كان هناك أي تقدم بالنسبة لك.

ولكن كما فهمت لم يتم دمج العلاقات العامة لنظام التشغيل Windows بعد

في الجمعة ، 26 يونيو 2020 ، الساعة 20:07 ، كتب Jan Gorecki ، [email protected] :

@ vk111 https://github.com/vk111 نعم ، بالضبط ما كنت أسأل عنه.
إذا كان بإمكانك التحقق من هذه الأشكال الثلاثة على جهاز Windows الخاص بك ومشاهدتها
إذا كان هناك أي تقدم بالنسبة لك.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650320224 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MMDOCNAWARCCDRSU23RYTPVFANCNFSM4I4ZPREA
.

4440 مدمج بالفعل ويساعد في كل نظام تشغيل. # 4558 لا يزال معلقًا للدمج.

تم بالفعل دمج @ vk111 # 4558 أيضًا

مرحبًا جان ، لقد أخذت نصيحتك مؤخرًا - # 4419
https://github.com/Rdatatable/data.table/issues/4419 يتعلق بمشكلتي
لذلك ليس لدي هذا الجزء الدقيق من الكود مع انضمام الأحرف
لكن على أي حال ، أشكرك على هذا التحسين ، أنا متأكد من أنه سيساعد كثيرًا
الناس في المستقبل إذا كنت تعتقد أن لديها أداء أفضل فأنا
أعتقد أنه يجب عليك فقط دمجها
شكرا لك

пт، 26 июн. 2020 г. س 20:29 ، يان جوريكي [email protected] :

4440 https://github.com/Rdatatable/data.table/pull/4440 موجود بالفعل

مدمجة ومساعدة لكل نظام تشغيل. # 4558
https://github.com/Rdatatable/data.table/pull/4558 لا يزال معلقًا إلى
دمج.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650330154 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MIN2P7BXMKG74Z7EKTRYTSIJANCNFSM4I4ZPREA
.

-
مع أطيب التحيات،
فاسيلي كوزنتسوف

تم دمج العلاقات العامة المذكورة بالفعل @ vk111 . المهم هو معرفة ما إذا تم حل هذه المشكلة أو على الأقل تحسينها. هؤلاء الممثلون الرئيسيون المدمجون لم يكونوا يحاولون حل هذه المشكلة ، لكنهم مرتبطون ببعضهم البعض لذا ربما كانوا مفيدون.

يحدث أن المثال الأدنى الذي تم الإبلاغ عنه في البداية كان يعرض المشكلة بشكل سيء. استنادًا إلى @ vk111 https://github.com/Rdatatable/data.table/issues/3928#issuecomment -538681316 لقد قمت بإنشاء مثال يوضح بوضوح أن هناك مشكلة هنا.

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 

يوضح مطولًا أن معظم الوقت يتم إنفاقه Calculated ad hoc index in 0.611s elapsed (0.769s cpu) ، وهو استدعاء forderv من bmerge .

نعم بالضبط
لكن يبدو أنه لا يوجد تحسن في هذه الاختبارات؟

في الثلاثاء ، 30 يونيو 2020 ، 00:45 ، كتب Jan Gorecki ، [email protected] :

يحدث أن المثال الأدنى الذي تم الإبلاغ عنه في البداية كان سيئ التعريض
المشكلة. بناءً على @ vk111 https://github.com/vk111 # 3928 (تعليق)
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-538681316
لقد قمت ببناء مثال يوضح بوضوح أن هناك مشكلة هنا.

مكتبة (جدول البيانات)
setDTthreads (2L)
set.seed (108) n2 = 1: 366000n1 = sample (n2، 30000) d1 = data.table (id1 =aste0 ("id"، sample (n1))، id2 =aste0 ("id"، sample (n1) )، v1 = n1) d2 = data.table (id1 =aste0 ("id"، sample (n2))، id2 =aste0 ("id"، sample (n2))، v2 = n2)
system.time (d2 [d1، v1: = i.v1، on = c ("id1"، "id2")])

3.4.0: 1.10.4-3

انقضى نظام المستخدم
0.144 0.000 0.144

3.4.0: 1.12.2

انقضى نظام المستخدم
0.611 0.003 0.451

3.4.0: 1.12.9

انقضى نظام المستخدم
0.611 0.000 0.452

4.0.0: 1.12.9

انقضى نظام المستخدم
0.812 0.004 0.644

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-651408089 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ABRM7MPQHSOEGLXS625BU3TRZEKSBANCNFSM4I4ZPREA
.

لا يوجد تحسن ، هذه لا تزال مشكلة.
بعد بعض الحفر وجدت أن عنق الزجاجة هو هذه المكالمة
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L282
الذهاب أبعد ...
هذه الحلقة مسؤولة عن 60٪
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L242 -L245
و 30٪
https://github.com/Rdatatable/data.table/blob/ba32f3cba38ec270587e395f6e6c26a80be36be6/src/forder.c#L252 -L258

حاولت التحقق مما إذا كان استخدام العناصر الداخلية R ( CHAR() ماكرو بدلاً من الوظيفة) سيساعد هنا ، لكنه لا يساعد.


أكثر من مجرد مثال بسيط ، التوقيت forderv فقط ، على 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 

حاولت التحقق مما إذا كان استخدام R الداخلية (CHAR () ماكرو بدلاً من وظيفة) سيساعد هنا ، لكنه لا يساعد.

هذا لأن R لم يعد يفعل ذلك بعد الآن. مع USE_RINTERNALS و INTEGER و REAL وأنا أفترض CHAR أيضًا ، لا تزال وظائف مضمنة. بمعنى آخر ، تمت إزالة ميزة USE_RINTERNALS (أي الماكرو بدلاً من الوظيفة) في الإصدارات الأخيرة من R للسماح باستخدام ALTREP. لا أعتقد أنه في الواقع ما إذا كان الأمر يتعلق بوظيفة ماكرو أو وظيفة مضمنة ، في حد ذاته ، هو ما يصنع الفارق. إنه ما يفعله R داخل وحدة العمل هذه. في الأيام الخوالي ، جعله USE_RINTERNALS ماكروًا وكان بحثًا مباشرًا عن الذاكرة (مرجع مصفوفة يأخذ فقط في الاعتبار رأس المتجه) وهذا هو السبب في أنه كان أسرع. كانت وحدة عمل خفيفة الوزن للغاية. في هذه الأيام ، لدى R فرع واحد على الأقل للتحقق من ALTREP ، وحتى مع توقع الفرع ، فإن هذا العمل الإضافي يضيف و / أو يمنع الجلب المسبق. بعبارة أخرى ، أصبح لدى R الآن رمز أكثر قليلاً داخل هذه الوظائف المضمنة. ليس لدي دليل معياري ، فقط نظرية مبنية على النظر إليها.

قد يكون السبب الأساسي هو إزالة الفرع التالي في cradix_r
https://github.com/Rdatatable/data.table/blob/76bb569fd7736b5f89471a35357e6a971ae1d424/src/forder.c#L780 -L783
والآن لا توجد دائرة قصر لإدخال الطول 2.
ليس من الواضح كيفية وضع هذا الفرع الآن لأن الوظيفة قد تغيرت كثيرًا من حيث كيفية عملها.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات