こんにちは、私はテストしていました
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)
以下を実行しました:
# 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)
次に、このプロットを作成するために次のことを行いました
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)
コミット時間をベンチマークに直接追加するには
こんにちは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
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.864docker 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.062docker 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.004Windowsを使用しているため、最終的には別の保留中の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
。
@ 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.1443.4.0:1.12.2
ユーザーシステムが経過しました
0.611 0.003 0.4513.4.0:1.12.9
ユーザーシステムが経過しました
0.611 0.000 0.4524.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の入力の場合、短絡はありません。
関数がどのように動作するかという点で大きく変わったため、今そのブランチをどのように配置するかは明らかではありません。