有没有提高这个哈希的初始化速度? 目前,我的机器需要大约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:并发可能是一种选择。但这并没有改善散列。
答案 0 :(得分: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
,所以附加元素只会随着它的大小增加而变得越来越慢。
答案 1 :(得分: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
答案 2 :(得分: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.001s。