私はブラケットを使用して増加し、ベクトルCONCATENATEを使用してサイズ、およびいずれかをテストするために次の2つの関数、1を書いた:Rでは、v [length(v)+1] = xがc(v、x)よりも優れているのはなぜですか?
c_test <- function(n) {
cv = c()
for(i in 1:n) cv = c(cv, i)
cv
}
b_test <- function(n) {
bv = c()
for (i in 1:n) bv[i] = i
bv
}
library(microbenchmark)
microbenchmark(c_test(1e+4), b_test(1e+4), times = 100)
#Unit: milliseconds
# expr min lq mean median uq max neval
# c_test(10000) 140.27923 145.73282 156.82319 148.16175 151.74713 267.2393 100
# b_test(10000) 49.58033 54.42992 56.24268 54.86033 56.30862 132.8394 100
これは大きな時間差で、ブラケットを使用することはそんなに優れている理由を私は理解していません連結を使用するよりも。どちらの場合も新しいメモリを割り当てるのに時間がかかるようですが、これは当てはまりません。また、c(v, x)
はx
をマージする前にv
と同じタイプに変換していますが、v[i] = as.vector(x)
と言ってもそれほど時間がかかりません。
ここで注意すべき点は、この動作が実際に何が起こっているのかを示唆する 'my_len'の値が低くなるためです。後者は、ベクターが成長するためにある程度の余分なスペースをあらかじめ割り当てるように見えますが、前者は常にコピーを作成します。事前割り当ては、コピーよりも小さいサイズでは遅くなります。 – Shape
実際には、800-900の範囲のマイレン(mylen)の右にフリップされます – Shape
事前割り当てなしで 'for'ループで使用されると、どちらも悪いです。 Rは、これらの時間のペナルティを避けるためにベクトル化された関数の周りに構築されています。 – alistaire