有一项能够加速大型复杂函数的简单技术叫做备忘(memoization),这是某种形式的缓存。当每次调用函数时,一个备忘函数会在table中储存被调函数的输入参数以及返回值。如果这个函数以同样的输入参数被再次调用时,它返回的就是储存在table中的值而不需要再次进行计算。
Clojure内建支持备忘的函数是memoize,它接收一个函数做为参数,返回这个函数的备忘版本:
(defn really-slow-function [x y z] ...) (def faster-function (memoize really-slow-function))
备忘是一个牺牲内存加速执行的经典例子。如果一个函数需要花费比哈希表寻址更多的时间去计算结果,而且它又经常以同样的输入参数被调用,那么采用备忘就是一种好的候选方案。只有纯函数--意即针对特定输入总是返回同样结果的函数--能够进行备忘。
“备忘”的定义
“memoization”(备忘)这个词是由Donald Michie在1968年提出的,它基于拉丁语单词“memorandum”(备忘录),意思是“被记住”。虽然它和单词“memorization”在某种程度上有些相似,但它并不是该单词的错误拼写。实际上,Memoisation是一种用于通过计算来加速程序的技术,它通过记住输入量的计算结果,例如函数调用结果,来实现其加速目的。如果遇到相同的输入或者具有相同参数的函数调用,那么之前存储的结果就可以被再次使用,从而避免一些不必要的计算。在很多情况下,可以使用一个简单的数组来存储结果,但也可以使用许多其他的数据结构,例如关联数组,它在Perl语言中叫做哈希,在Python语言中称为字典。
备忘功能可以由程序员显式地编程实现,但是一些编程语言如Python,都提供了自动备忘函数的机制。