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