Data.table: 結合操作はほぼ2倍遅くなります

作成日 2019年10月02日  ·  29コメント  ·  ソース: Rdatatable/data.table

こんにちは、私はテストしていました
data.table_1.10.4-3 + Rバージョン3.4.0(2017-04-21)
vs
data.table_1.12.2 + Rバージョン3.6.1(2019-07-05)

新しいバージョンのdata.table(R?)では、結合操作がほぼ2倍遅くなっていることに気づきました。
私は主に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

全てのコメント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、私は2回読んだ
しかし、2016年から2019年までのタイムラインは正確にはどういう意味ですか? それはdatatableのバージョンですか?

バージョンだけでなく、特定のコミット。 バージョンの境界を追加してみましょう。追加するのを忘れたのは良い考えです。

@MichaelChiricoグラフはとてもクールに見えますが、欠けていたのはその解釈でした:)推測すると、新しい並列フォーダーは、長さ100の入力では以前よりも遅くなります。 これらはまだマイクロ秒であるため、どのIMOで問題ありません。 もちろん、オーバーヘッドを削減することは価値がありますが、最も一般的な使用シナリオでは、リソースの削減を優先する必要があります。 長さ100の入力で10000回ループすることは、間違いなくその1つではありません。

1.12.0 NEWSを見た後も、それは私の推測でした。 シングルスレッドを再実行しようとします。

@jangorecki 、簡単な計算を行うと、数千マイクロ秒、つまりミリ秒になります
このテストのインスピレーションは、40000行の7〜8回のテーブルを結合する現在のプロジェクトでした。
18秒かかる前、40秒かかった後
私のテストには文字キーも含まれています
3.6 + 1.12をインストールしてから、3.4 +1.10にロールバックしました
これは通常の状況ではないと思うので、この問題がここにあります

はい、グラフは本当に素晴らしいです。 これをもっと行い、自動化する必要があります。

ただし、元のレポートでは、R3.4とR3.6を比較しています。R3.6は中央にR3.5があります。 R 3.5は、ALTREPによるREAL()、INTEGER()のマクロから(少し重い)関数への変更によってdata.tableに影響を与えたことがわかっています。

@ vk111CRANでv1.12.4を使用してテストを再実行してください。 何か良いですか? R 3.5以降に対処するために、RAPIの外部ループを使用しています。 次のステップとして、v1.12.4を見つける方法を知っておくと便利です。 マシンに関する詳細情報も含めることができますか。 たとえば、オペレーティングシステム、RAM、CPUの数。

@matt 、します

こんにちは@mattdowle

Iveを1.12.4(+ R 3.6.1)に更新しました-基本的に、ユニットテストと私の関数には同じ番号があります
ここでは、インデックスなしで文字と結合するだけであると考えます-ベンチマークとして
ユニットテスト(最初の投稿で述べたように)
3.6.1:インデックスなしで6.87秒
3.4.0:3.02秒(インデックスなし)

プロジェクトからの私の機能は同じままです:20秒対40秒
〜14dtの結合のみで構成されます
2つのテーブル30000行(dt1)と366 000行(dt2)
各15列
キーは2文字と1つの数字です
結合中に7つのフィールド(dt1からdt2まで)が割り当てられました

私のPC:
Win 1064ビット
AMD A8 2.2 Ghz
8 Gb RAM

cmd:wmic cpu get NumberOfCores、NumberOfLogicalProcessors / Format:List
NumberOfCores = 4
NumberOfLogicalProcessors = 4

分析ありがとうございます

こんにちは@mattdowleだから、これを検討していますか?

私が再実行したばかりのgit bisectによると、このコミットはスローダウンに対して「有罪」であり、マットがルートを特定するのに役立つことを願っています。 それが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)

これらの2つのスクリプトを使用して、 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のコミットは、私のマシンでは反復ごとに約.9秒かかり、 goodのコミットは約.7でした。

こんにちはマイケル、ありがとうございますが、パフォーマンスは特に劇的に低下しました
文字キーの場合-最初の投稿でユニットテストを提供しました
とにかく、それが修正されたかどうかマットからの確認を待つ必要があると思います
新しいバージョンかどうか

2019年12月26日木曜日15:02、Michael [email protected]
書きました:

私が再実行したgitbisectによると、このコミットは「有罪」です。
速度を落とすと、マットがルートを特定するのに役立つことを願っています。 それは
フォーダーに関連して、私たちはそれをピン留めしたことを比較的確信しています
正しく。

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

より正確に:

run_join_time.sh

R CMDINSTALL。 && Rscript time_join.R

time_join.R

ライブラリ(data.table)
ライブラリ(マイクロベンチマーク)

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:= ib、on =。(a)])$ time / 1e6)

これらの2つのスクリプトを使用して、master / HEADから:

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

次に、各反復で、sh run_join_time.shを実行し、結果を確認します。 The
不正なコミットは、私のマシンでは反復ごとに約.9秒かかりました。
.7についての良いコミット。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MJQITNUZDNYV7NTIX3Q2S2ORA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN
または購読を解除する
https://github.com/notifications/unsubscribe-auth/ABRM7MOTZRFFM2QKVFUHT6LQ2S2ORANCNFSM4I4ZPREA

>>

よろしくお願いします、
ヴァシーリー・クズネツォフ

@ vk111この問題が解決されていない場合は、問題がまだ修正されていないと安全に想定できます。 何かを修正するたびに、関連する問題を閉じます。

@ vk111 setindex setkeyを使用すると、いくつかの小さな調整で軽減できる場合があります。 これにより、私のコンピューターでのテストが半分以上削減されます。

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のようなものがあります
結合すると、文字列が非常に動的になり、
20回のsetkeyと20のように、参加する前に毎回setkeyを作成する必要があります
時間は結合するため、時間の増加は2倍未満です
この状況の一般的な回避策として、私はしばらくの間3.4.0を使用しています
特に新しいバージョンで修正するのは大したことではありません
有罪判決が見つかりました
ちなみにリンゴとリンゴを比較すると3.4(1.10)は
セットキーで同じ単体テストを使用した場合、3.6(1.12)よりもさらに高速です。
両方のバージョン
幸せな休日

2019年12月29日、日曜日、14:48 Cole Miller、 notifications @ github.comは次のように書いています。

@ vk111https ://github.com/vk111いくつかの方法で軽減できる可能性があります
setindexの代わりにsetkeyを使用したマイナーな調整。 これはあなたのテストをカットします
私のコンピューターの半分以上:

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

チック()
for(i in c(1:1000)){
aa [bb、b:= ib、on =。(a、a1)]#キーなしのtest1
}
toc()

4秒経過

チック()
setkey(aa、a、a1)
setkey(bb、a、a1)

for(i in c(1:1000)){
aa [bb、b:= ib]#キーなしのtest2
}
toc()

1.46秒経過

【画像:画像】
https://user-images.githubusercontent.com/57992489/71557665-126d7880-2a17-11ea-8664-21a10deb47ca.png

ライブラリ(マイクロベンチマーク)
ライブラリ(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)

チック()
aa_int_key = setkey(copy(aa)、a)
bb_int_key = setkey(copy(bb)、a)
toc()

チック()
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、on =。(a)]
}

int_key = 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)]
}

箱ひげ図(
マイクロベンチマーク(
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)
)。
)。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/Rdatatable/data.table/issues/3928?email_source=notifications&email_token=ABRM7MPU64YBK7UNT3O3OYDQ3CTBRA5CNFSM4I4ZPREKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW
または購読を解除する
https://github.com/notifications/unsubscribe-auth/ABRM7MKSP6LCUJD2HOAG7D3Q3CTBRANCNFSM4I4ZPREA

関連する保留中のPR#4370があります。 [が通常課すより少ないオーバーヘッドで結合を行うことができます。 これにより、例のタイミングが2分の1に短縮されます。データが大きいほど、改善は小さくなりますが、一方で、反復回数が多いほど、改善は向上します。 結合中に列を更新する方法がないことに注意してください。 基本的に、結合中に列を追加してから、 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

こんにちはヤン、OKありがとう

データが大きいほど、改善は小さくなりますが、一方で、
反復回数が多いほど、改善が向上します
本当の問題はビッグデータと数回の反復に関連しています-私はそれを書きました
その上

2020年5月4日月曜日、00:33 Jan Gorecki、 notifications @ github.comは次のように書いています。

保留中の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(aa、a)
setindex(bb、a)p = proc.time()[[3L]] for(i in c(1:1000)){
aa [bb、b:= ib、on =。(a)]
}
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(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


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-623193573
または購読を解除する
https://github.com/notifications/unsubscribe-auth/ABRM7MJR5THRHE3FIXXV3YTRPXWNNANCNFSM4I4ZPREA

#4440(昨日マージ)でこの問題が解決するかどうかを確認しましたが、解決しないようです。 ここで取得するタイミングは@ vk111によって報告されたタイミングとはかなり異なりますが、最近の開発バージョンをテストして、ワークフローに役立つかどうかを確認してください。
Windowsを使用しているため、最終的に#4558に役立つ可能性のある別の保留中のPRがあります。


これは、各環境で実行する一般的なスクリプトです。

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を使用しています

2020年6月26日金曜日、13:19 Jan Gorecki、 notifications @ github.comは次のように書いています。

#4440https ://github.com/Rdatatable/data.table/pull/4440かどうかを確認しました
この問題は解決しましたが、解決しなかったようです。 タイミングは取れますが
ここでは、@ vk111によって報告されたタイミングとはかなり異なります
https://github.com/vk111なので、最近の開発をテストできる場合
バージョンを作成し、ワークフローに違いが生じるかどうかを確認します。
役に立った。
これは、各環境で実行する一般的なスクリプトです。

ライブラリ(data.table)
setDTthreads(2)## vk111には4つのコアがあります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( "test1n")
system.time({for(i in c(1:1000)){
aa [bb、b:= ib、on =。(a、a1)]#test1
}})
cat( "test2n")
system.time({for(i in c(1:1000)){
aa [bb、b:= ib、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
ユーザーシステムが経過しました
0.949 0.007 0.957
test2
ユーザーシステムが経過しました
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
ユーザーシステムが経過しました
2.598 0.047 1.350
test2
ユーザーシステムが経過しました
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")
test1
ユーザーシステムが経過しました
1.174 0.045 1.219
test2
ユーザーシステムが経過しました
0.981 0.024 1.004

Windowsを使用しているため、最終的には別の保留中のPRが発生する可能性があります
ヘルプ#4558https ://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マシンでこれらの3つの構成を確認し、進捗状況があるかどうかを確認できますか。

しかし、私が理解したように、Windowsのprはまだマージされていません

2020年6月26日金曜日、20:07 Jan Gorecki、 notifications @ github.comは次のように書いています。

@ vk111 https://github.com/vk111はい、まさに私が求めていたものです。
Windowsマシンでこれらの3つの構成を確認して、
何か進歩があれば。


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-650320224
または購読を解除する
https://github.com/notifications/unsubscribe-auth/ABRM7MMDOCNAWARCCDRSU23RYTPVFANCNFSM4I4ZPREA

4440はすでにマージされており、すべてのOSに役立ちます。 #4558はまだマージを保留しています。

@ vk111 #4558もすでにマージされています

こんにちはヤン、私は最近あなたのアドバイスを受けました-#4419
私の問題に関連するhttps://github.com/Rdatatable/data.table/issues/4419
だから私は文字が結合されたこの正確なコードを持っていません
しかしとにかくこの改善に感謝します私はそれが多くの助けになると確信しています
将来の人々は、それが私よりも優れたパフォーマンスを持っていると信じているなら
あなたはそれをマージする必要があると思います
ありがとう

пт、26日。 2020г。 в20:29、Jan [email protected]

4440https ://github.com/Rdatatable/data.table/pull/4440はすでに

マージされ、すべてのOSに役立ちます。 #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が言及したPRはすでにマージされています。 問題は、この問題が解決されたか、少なくとも改善されたかを知ることです。 これらのマージされたPRはこの問題を解決しようとしていませんでしたが、関連しているため、役に立った可能性があります。

最初に報告された最小限の例では、問題が十分に公開されていなかったことがあります。 @ 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 

verboseは、ほとんどの時間がCalculated ad hoc index in 0.611s elapsed (0.769s cpu)に費やされていることを示しています。これは、 bmerge fordervへの呼び出しです。

はい、正確に
しかし、このテストには改善がないようですか?

2020年6月30日火曜日、00:45 Jan Gorecki、 notifications @ github.comは次のように書いています。

最初に報告された最小限の例は、露出が不十分だったことが起こります
問題。 @ vk111に基づくhttps://github.com/vk111#3928 (コメント)
https://github.com/Rdatatable/data.table/issues/3928#issuecomment-538681316
ここに問題があることを明確に示す例を作成しました。

ライブラリ(data.table)
setDTthreads(2L)
set.seed(108)n2 = 1:366000n1 = sample(n2、30000)d1 = data.table(id1 = past0( "id"、sample(n1))、id2 = pastet0( "id"、sample(n1) )、v1 = n1)d2 = data.table(id1 = past0( "id"、sample(n2))、id2 = past0( "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のみ、R4.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もインライン関数であると想定します。 つまり、最近のバージョンのRでは、ALTREPを許可するために、USE_RINTERNALSの利点(つまり、関数ではなくマクロ)が削除されました。 違いを生むのは、それ自体がマクロか関数かインライン関数かということではないと思います。 それは、その作業単位内でRによって行われていることです。 昔は、USE_RINTERNALSはそれをマクロにし、それは直接メモリルックアップ(ベクトルのヘッダーを考慮した配列の逆参照)であったため、より高速でした。 非常に軽量な作業単位でした。 最近、RにはALTREPをチェックするための少なくとも1つの分岐があり、分岐予測があっても、余分な作業が追加されたり、プリフェッチが妨げられたりします。 言い換えると、Rはこれらのインライン関数内にもう少しコードを持っています。 私にはベンチマークの証拠はなく、それを見て基づいた理論だけです。

根本的な原因は、 cradix_r内の次のブランチの削除である可能性があります
https://github.com/Rdatatable/data.table/blob/76bb569fd7736b5f89471a35357e6a971ae1d424/src/forder.c#L780 -L783
そして今、長さ2の入力の場合、短絡はありません。
関数がどのように動作するかという点で大きく変わったため、今そのブランチをどのように配置するかは明らかではありません。

このページは役に立ちましたか?
0 / 5 - 0 評価