值得注意的是,Knuth 的原始引用来自他撰写的一篇论文,该论文宣传在精心挑选和测量的区域中使用 goto 作为消除热点的一种方式。他的引用是他添加的一个警告,以证明他使用goto 来加速这些关键循环的理由。
[...] 再次,这明显节省了整体运行速度,
例如,如果 n 的平均值约为 20,并且如果搜索例程
在程序中执行大约一百万次左右。这样的循环
优化 [使用 gotos] 并不难学,而且正如我所学
说,它们只适用于程序的一小部分,但它们
往往会带来可观的节省。 [...]
然后继续:
当今许多软件工程师所共有的传统智慧
呼吁忽略小事的效率;但我相信这是
只是对他们看到的滥用行为的过度反应
不会调试或维护的傻瓜程序员
他们的“优化”程序。在已建立的工程学科中
12% 的改进,很容易获得,从不被认为是微不足道的;和我
相信同样的观点应该在软件工程中占上风。的
当然我不会费心在一次性工作上进行这样的优化,
但是当它是一个准备质量程序的问题时,我不想要
限制自己使用无法获得这种效率的工具 [即,goto
在这种情况下的陈述]。
请记住他如何在引号中使用“优化”(该软件可能实际上并不高效)。还要注意他不仅批评了这些“一分钱一分货”的程序员,还批评了那些建议你总是忽略小的低效率的人。最后,到经常被引用的部分:
毫无疑问,效率的圣杯会导致滥用。
程序员浪费大量时间思考或担忧
关于,他们程序的非关键部分的速度,以及这些
提高效率的尝试实际上会产生强烈的负面影响
考虑调试和维护。我们应该忘记小
效率,比如说 97% 的时间;过早优化是根本
万恶之源。
...然后更多地了解分析工具的重要性:
先验地判断一个项目的哪些部分通常是错误的
程序真的很关键,因为普遍的经验
一直在使用测量工具的程序员
直觉猜测失败。在使用这些工具七年之后,
我已经确信从现在开始编写的所有编译器都应该是
旨在为所有程序员提供反馈,指出什么
他们的部分项目成本最高;确实,这个反馈
应自动提供,除非已明确
关闭。
人们到处都在滥用他的话,当他的整篇论文都在提倡微优化时,他经常暗示微优化还为时过早!他批评的一群人呼应了这种“传统智慧”,因为他总是忽略小事的效率,他们经常滥用他的引述,该引述最初是针对那些不鼓励所有形式的微优化的类型的人。 .
然而,当经验丰富的手持分析器使用时,它是支持适当应用微优化的引用。今天的类比等价物可能是,“人们不应该盲目地优化他们的软件,但自定义内存分配器在应用于关键领域以提高引用的局部性时可以产生巨大的影响,” 或, "使用 SoA 代表的手写 SIMD 代码确实很难维护,您不应该到处使用它,但如果由经验丰富且有指导的人适当应用,它会更快地消耗内存。"
每当您尝试推广如 Knuth 上面所推广的仔细应用的微优化时,最好加入免责声明,以阻止新手过于兴奋和盲目地尝试优化,例如重写他们的整个软件以使用goto。这部分是他正在做的。他的引述实际上是一个大免责声明的一部分,就像骑摩托车跳过燃烧的火坑的人可能会添加一个免责声明,即业余爱好者不应该在家里尝试这个,同时批评那些在没有适当知识和设备的情况下尝试并受伤的人.
他认为“过早的优化”是那些实际上不知道自己在做什么的人应用的优化:不知道优化是否真的需要,没有使用适当的工具进行衡量,也许不明白他们的编译器或计算机体系结构的性质,最重要的是,是“一分钱一磅的愚蠢”,这意味着他们忽略了优化(节省数百万美元)的大机会,试图捏几分钱,同时创建代码他们无法再有效地调试和维护。
如果您不属于“一分钱一磅-愚蠢”类别,那么即使您使用goto 来加快关键进程,您也不会过早按照 Knuth 的标准进行优化循环(这对当今的优化器不太可能有太大帮助,但如果确实如此,并且在真正关键的领域,那么您就不会过早地进行优化)。如果您实际上将您正在做的任何事情应用到真正需要的领域并且他们真正从中受益,那么您在 Knuth 眼中就做得很好。