编写大型程序时,我为全局变量使用较长的名字(10 个或 20 个字符)。本章使用了像 x、n 和 t 这样的短变量名。在大多数软件项目中,最短的合理名称可能类似于 elem、nelems 和 target。我发现建立脚手架的时候使用短名字比较方便,在类似 4.3 节的数学证明中使用短名字也是很必要的。数学上也有类似的法则:对数学不熟悉的人可能希望听到“直角三角形斜边的平方等于两条直角边的平方和”,而处理该问题的人通常会说“a^2+b^2=c^2”。
搜索“mutation testing”之类的术语。
仅进行 O(log n) 或 O(1) 次额外的比较,如何实现?
本书网站上提供了一个带有图形用户界面的 Java 程序,可用于研究排序算法。
7. 5.5 节的计时脚手架有一个潜在的计时错误:通过按顺序搜索每个元素,我们获得了非常有利的缓存性能。如果已知在潜在的应用中搜索是按相似的方式进行的,那么这是一个正确的程序框架(但是那样的话二分搜索恐怕并不是一个恰当的工具)。但是,如果我们希望搜索算法对数组的探测随机进行,那么我们也许还应该初始化并打乱一个排列向量,然后按随机顺序执行搜索。度量这两个版本的运行时间,看看是否存在差异。
当 n=1000 时,按照排好的顺序搜索整个数组每次需要 351 纳秒,而按随机顺序搜索会使平均开销提高到 418 纳秒(大约减慢 20%)。当 n=10^6 时,实验中甚至连二级缓存都会溢出,并且减速因子为 2.7。对于 8.3 节中高度调优过的二分搜索,有序搜索能够在 125 纳秒内搜索包含 n=1000 个元素的表,而随机搜索则需要 266 纳秒的时间,减速因子超过 2。
脚手架以制表符作为分隔符,这种输出格式能够兼容大多数的电子表格。我通常将一系列的相关实验和它们的性能图表存储在同一页电子表格上,并在该页说明为什么做这些实验以及从中能学到什么。