2

このハッシュの初期化の速度を改善する方法はありますか?現在、これは私のマシンでは約20分かかります。

#prepare hash()
hash <- list();

mappedV <- # matrix with more than 200,000 elements
for( i in 1:nrow(mappedV) ) {
  hash[[paste(mappedV[i,], collapse = '.')]] <- 0;
}

このコードの前に、私はマトリックスを使用しましたが、これには3時間以上かかりました。だから私は20分について文句を言うことはありません。より良い選択肢があるかどうか私はただ興味があります。ハッシュ関数を使用して、200,000の可能な組み合わせのそれぞれをカウントします。

PS:並行性を実現することはおそらく1つの選択肢です。しかし、これはハッシュを改善しません。

4

3 に答える 3

5

多くの場合、反復ごとにリストを増やすのではなく、必要な長さのリストを事前に割り当てることで、大幅な時間を節約できます。

見よ:

X <- vector(mode="list", 1e5)
Y <- list()

system.time(for(i in 1:1e5) X[[i]] <- 0)
#    user  system elapsed 
#     0.3     0.0     0.3 
system.time(for(i in 1:1e5) Y[[i]] <- 0)
#    user  system elapsed 
#   48.84    0.05   49.34 
identical(X,Y)
# [1] TRUE

リスト全体Yが追加されるたびにコピーされるため、追加の要素の追加は、サイズが大きくなるにつれてますます遅くなります。

于 2013-02-16T21:03:18.923 に答える
4

ハッシュとしても使用できますenvironment...見てみましょう:

mappedV <- matrix(1:100000, ncol=5)
hash1 <- list()
hash2 <- new.env(hash=TRUE)

system.time(for(i in 1:nrow(mappedV)) hash1[[paste(mappedV[i,], collapse = '.')]] <- 0)
#   user  system elapsed 
# 19.263   1.321  21.634 

system.time(for(i in 1:nrow(mappedV)) hash2[[paste(mappedV[i,], collapse = '.')]] <- 0)
#   user  system elapsed 
#  0.426   0.002   0.430 

「注意事項」に回答するように更新

Josh O'Brienが指摘したように、変更時に環境全体がコピーされないため、これは非常に高速です。便利そうですね。

「問題」は、これらのオブジェクトが、その不変性に関して、慣れ親しんだ他のほとんどのオブジェクトと同じように動作することを期待している場合に発生する可能性があります。がenvironmentどこかで変更されると、どこでも変更されます。たとえば、environmentすべての要素を削除する関数にを渡すenvironmentと、リストはどこにでも行き渡りますが、リストはそうではありません。

目撃者:

hash1 <- list(a=1:10, b=rnorm(10))
hash2 <- new.env(hash=TRUE)
hash2$a <- 1:10
hash2$b <- rnorm(10)

danger <- function(x, axe) {
  for (wut in axe) x[[wut]] <- NULL
}

## the list is safe
danger(hash1, names(hash1))
hash1
# $a
#  [1]  1  2  3  4  5  6  7  8  9 10
#
# $b
# [1] -0.8575287  0.5248522  0.6957204 -0.7116208
# [2]  0.5536749  0.9860218 -1.2598799 -1.1054205
# [3]  0.3472648

## The environment gets mutilated
danger(hash2, names(hash1))
as.list(hash2)
# $a
# NULL
# 
# $b
# NULL
于 2013-02-16T21:17:39.083 に答える
2

環境を使用するほど速くはありませんが、問題に対する簡単なベクトル化された解決策があります。

mappedV <- matrix(1:100000, ncol = 5)
hashes <- apply(mappedV, 1, paste, collapse = ".")

hash <- list()
hash[hashes] <- 0

またはもちろん、0のベクトルをリストに変換して名前を付けることもできます。

hash <- as.list(rep(0, length = length(hashes)))
names(hash) <- hashes

それは私のコンピュータでは<0.001秒かかります。

于 2013-02-17T18:29:56.370 に答える