我正在缓存函数f(1),f(2),...,f(1e7)的结果。缓存中的元素将随机读取。在C中,我将其存储在向量中,因为访问复杂度为O(1)。在Perl中,我应该将缓存存储在向量还是哈希?
我觉得将它存储在哈希中并不会利用输入是连续整数的事实。但另一方面,我可能会过度思考这一点。
答案 0 :(得分:7)
不要自己缓存函数的结果,而是使用为您处理它的Memoize core module。
use Memoize;
memoize('slow_function');
slow_function(arguments); # Is faster than it was before
这就是它的全部内容,它已存在很长时间并经过充分测试。
答案 1 :(得分:2)
除了通常的免责声明关于效率的担忧,直到你描述,我会说它存储在一个数组中。哈希在计算哈希密钥时会产生额外的开销。此外,数组是最自然的表示形式,除非你知道你的表现没有,否则为了清晰起见。
答案 2 :(得分:1)
Perl中的数组和散列都是O(1)。但是,我敢打赌,阵列的O(1)在绝对时钟时间上更快。在后序整数的情况下,数组可能比其简单的索引数学更快。
答案 3 :(得分:0)
访问存在的数组元素比插入哈希更快。从好的方面来说,两者的表现同样相称。 (复杂性分析衡量某些东西的缩放程度,而不是它的速度。)
数组元素的最坏情况访问:
$x = $a[$i]; # O(1)
$a[$i] = $x; $i<@a # O(1)
$a[$i] = $x; # O(1), amortized
哈希元素的最坏情况访问(对于有限长度的键):
$x = $h{$k}; # O(1)
$h{$k} = $x; # O(1), amortized
(“摊销的O(1)”表示这些操作中的N为O(N)。)
鉴于你的键是连续的整数,你绝对应该使用数组。
my @cache;
sub func {
my ($n) = @_;
return $cache[$n] //= ...;
}
如果您的密钥稀疏,那么最好使用散列来节省内存。
my %cache;
sub func {
my ($n) = @_;
return $cache{$n} //= ...;
}