【发布时间】:2011-03-29 01:54:48
【问题描述】:
在使用 R 之前,我使用了相当多的 Perl。在 Perl 中,我经常使用哈希,而在 Perl 中,哈希查找通常被认为是快速的。
例如,以下代码将使用最多 10000 个键/值对填充散列,其中键是随机字母,值是随机整数。然后,它会在该哈希中进行 10000 次随机查找。
#!/usr/bin/perl -w
use strict;
my @letters = ('a'..'z');
print @letters . "\n";
my %testHash;
for(my $i = 0; $i < 10000; $i++) {
my $r1 = int(rand(26));
my $r2 = int(rand(26));
my $r3 = int(rand(26));
my $key = $letters[$r1] . $letters[$r2] . $letters[$r3];
my $value = int(rand(1000));
$testHash{$key} = $value;
}
my @keyArray = keys(%testHash);
my $keyLen = scalar @keyArray;
for(my $j = 0; $j < 10000; $j++) {
my $key = $keyArray[int(rand($keyLen))];
my $lookupValue = $testHash{$key};
print "key " . $key . " Lookup $lookupValue \n";
}
现在,我越来越想在 R 中使用类似哈希的数据结构。以下是等效的 R 代码:
testHash <- list()
for(i in 1:10000) {
key.tmp = paste(letters[floor(26*runif(3))], sep="")
key <- capture.output(cat(key.tmp, sep=""))
value <- floor(1000*runif(1))
testHash[[key]] <- value
}
keyArray <- attributes(testHash)$names
keyLen = length(keyArray);
for(j in 1:10000) {
key <- keyArray[floor(keyLen*runif(1))]
lookupValue = testHash[[key]]
print(paste("key", key, "Lookup", lookupValue))
}
代码似乎在做同样的事情。但是,Perl 更快:
>time ./perlHashTest.pl
real 0m4.346s
user **0m0.110s**
sys 0m0.100s
与 R 相比:
time R CMD BATCH RHashTest.R
real 0m8.210s
user **0m7.630s**
sys 0m0.200s
是什么解释了这种差异? R 列表中的查找不是很好吗?
增加到 100,000 个列表长度和 100,000 次查找只会夸大差异? R 中的哈希数据结构是否有比原生 list() 更好的替代方案?
【问题讨论】:
-
我不确定您是否与哈希结构本身结婚。也许您对更类似于 R 的做事方式感兴趣。如果是这样,请在您的问题中添加一个相对详细的哈希表用途示例。
-
顺便说一句,与 perl 相比,目前尚不清楚是什么减慢了速度。它可能是您的字符串生成(在 perl 中速度很快)。此外,您正在做一些非 R 之类的事情......请参阅我的回答。
-
我认为这是散列,根据下面文斯的回答。我的实际代码涉及遍历一个列表,为列表中的每个项目从带有 RMySQL 的数据库中选择,进行一些计算,然后更新数据库。我可以稍后发布一个更好的例子。谢谢。
-
此外,即使我的 R 代码不是以类似 R 的方式编写的(尤其是 for 循环),R 和 Perl 中的简单 for 循环也应该以大致相同的速度运行。我希望我的演示能够隔离 R 的 list() 和 Perl 的哈希之间的差异。我实际上试图做的是缓存一些我需要重复使用的临时结果。