3.3 好主意
既优秀又简单的主意不太多,能到处使用的非常少。缓存技术是其中之一。网页浏览器缓存了从网络取回的文档。当第二次要求同一个文档时,浏览器从本地磁盘或内存取回缓存了的副本,这很快,不用再次下载。域名服务器缓存了它从远端服务器收到的回复。当第二次搜索同样的名字时,本地服务器已经准备好了回复而不必进行可能耗时的网络通信了。当操作系统从磁盘读取数据时,它可能把数据缓存在内存里,以防该数据被再次读取;当CPU从内存获取数据时,它把数据缓存在特殊的缓存内存里,它比普通的主存更快。
缓存技术在真实的程序中反复出现。几乎任何含有带缓存技术的函数的程序都可能在性能上获益。然而缓存技术最好的特点是它是机械的(mechanical)。如果想让一个函数更快,可以重写函数或引入更好的数据结构或更精妙的算法。这可能需要独创性,它总是稀有的。但是添加缓存技术不需要动脑筋,缓存技术转换总是几乎一样的。如下:
sub some_function {
$result = some computation involving @_;
return $result;
}
转换成:
{ my %cache;
sub some_function_with_caching {
my $key = join ',', @_;
return $cache{$key} if exists $cache{$key};
$result = the same computation involving @_;
return $cache{$key} = $result;
}
}
这个转换对所有函数几乎都完全一样。唯一需要改变的部分是join ',', @_这行。这行要把函数的参数数组转换成一个字符串,以适合作为散列的键。像这样把任意值转变成字符串,这被称为序列化(serialization)或marshalling。先前的join ',', @_的例子仅对那些参数是数字或不含逗号的字符串的函数有效。后面将更仔细地介绍缓存的键的生成。