Прежде чем использовать 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, чем собственный список()?