“过早的优化是万恶之源”,这几乎是我们所有人都听过/读过的。我很好奇什么样的优化不是过早的,即在软件开发的每个阶段(高级设计,详细设计,高级实现,详细实现等),我们可以考虑的优化程度是什么,而不必跨入阴暗面。
“过早的优化是万恶之源”,这几乎是我们所有人都听过/读过的。我很好奇什么样的优化不是过早的,即在软件开发的每个阶段(高级设计,详细设计,高级实现,详细实现等),我们可以考虑的优化程度是什么,而不必跨入阴暗面。
Answers:
当您基于经验时?不邪恶。“每次我们使用X时,都会遭受性能的残酷打击。让我们计划这次优化或完全避免使用X。”
什么时候相对不痛?不邪恶。“以Foo或Bar来实现这一目标将花费同样多的工作,但从理论上讲,Bar应该效率更高。让我们来吧。”
当您避免笨拙的算法会严重扩展时?不邪恶。“我们的技术负责人说,我们提出的路径选择算法在阶乘时间内运行;我不确定这意味着什么,但她建议我们甚至考虑考虑使用seppuku。让我们考虑其他因素。”
邪恶来自花费大量时间和精力解决实际上不存在的问题。当问题确实存在时,或者当幻影伪问题可以廉价地解决时,邪恶就消失了。
Steve314和Matthieu M.在应考虑的评论中提出了观点。基本上,某些类型的“无痛”优化根本不值得,或者因为它们提供的微不足道的性能升级不值得代码混淆,它们正在复制编译器已经在执行的增强功能,或者两者都没有。请参阅注释,以获取一些过于巧妙的非改进示例。
i
未签名,i / 2
则可以替换为i >> 1
。它更快。但这也更加神秘(并不是每个人都会看到效果,即使是这样做的人也可能会浪费时间)。但是最糟糕的是编译器仍然会这样做,所以为什么要混淆源代码;)?
i/2
确实是一个热点,并且(确实令人难以置信,但让我们假设)i>>1
使a更快,那就去做,然后对它进行评论,以表明此剖析表明它更快。如果确实在任何地方都需要这样做(我对此表示怀疑,因为正如Matthieu所说,编译器应该足够聪明才能自己执行此操作),那么新手将学到一些东西,如果不需要(可能),为什么要插入他们的头上有不必要的民间传说?
应用程序代码仅应尽可能好,但库代码应尽可能好,因为您永远不知道如何使用库。因此,当您编写库代码时,它在各个方面都必须是好的,无论是性能,健壮性还是任何其他类别。
另外,在设计应用程序和选择算法时,还需要考虑性能。如果不是为了实现高性能而设计的,那么以后没有任何程度的黑客可以使它具有高性能,并且任何微优化都不会超过高级算法。
什么时候优化不是过早的,因此不是邪恶的?
善与恶是很难说的。谁拥有这项权利?如果我们看自然,似乎我们已经为生存编程了“生存”的广义定义,其中包括将我们的基因传给后代。
因此,至少根据我们的基本功能和编程,我想说的是,优化与复制目标保持一致时,它并不是邪恶的。对于男生,有金发,黑发,红发,很多可爱。对于女孩来说,有男人,其中一些似乎还可以。
也许我们应该为此目的进行优化,在那里使用分析器会有所帮助。探查器将为您提供有关热点及其发生原因的详细信息,从而使您可以更有效地对优化进行优先级划分和时间安排。这将使您有更多的空闲时间用于复制及其追求。
在所有情况下,您都应该根据自己的经验选择一个“足够好”的解决方案。
最优化的说法是在实际知道有必要之前编写“比'足够好'的代码复杂得多的代码,以使其更快”,因此使代码比必需的更加复杂。复杂性使事情变得困难,所以这不是一件好事。
这意味着您不应该选择一个超级复杂的“可以通过透明交换到磁盘来分类100 Gb文件的磁盘”排序例程,但是简单的排序应该是一个很好的选择。盲目选择Bubble Sort或“随机选择所有条目,并查看它们是否顺序一致。重复。” 很少好。
我的一般经验法则:如果您不确定是否需要优化,请假设您不需要。但请记住,何时需要进行优化。但是,您可能需要预先了解一些问题。这通常涉及选择好的算法和数据结构。例如,如果您需要检查集合中的成员资格,则可以肯定地确定您将需要某种类型的集合数据结构。
以我的经验,在详细的实施阶段,答案在于对代码进行概要分析。重要的是要知道什么需要更快,什么可以被接受。
了解确切的性能瓶颈在哪里也很重要-优化代码的一部分仅花费总运行时间的5%就不会有任何好处。
步骤2和3描述了非过早的优化:
我只知道回答这个问题的一种方法,那就是获得性能调整方面的经验。这意味着-编写程序,然后在编写程序之后,在其中找到加速并进行迭代。这是一个例子。
这是大多数人犯的错误:他们尝试在实际运行程序之前对其进行优化。如果他们上了一门编程课程(实际上是没有多少实践经验的教授),他们将戴上大O型彩色眼镜,他们会以为这就是全部。都是相同的问题,需要事先进行优化。**
有人说:首先要正确,然后再快速。他们是对的。
但是现在要考虑的是:如果您做了几次,您就会意识到您之前所做的愚蠢的事情会导致速度问题,因此您本能地避免了它们。(诸如使您的类结构变得过于沉重,被通知淹没,使函数调用的大小与它们的时间开销相混淆的事情,该列表会不断出现……)您本能地避免了这些,但请猜测一下这看起来是什么-经验丰富:过早的优化!
因此,这些愚蠢的辩论一直在继续:)
**他们说的另一件事是,您不必再为它担心,因为当今的编译器非常好,并且计算机非常快。(KIWI-用Iron杀死它。)没有指数级的硬件或系统加速(由非常聪明的勤奋的工程师完成)可以补偿指数级的软件速度下降(由以这种方式思考的程序员完成)。
“过早的优化是万恶之源”是我们几乎所有人都读/读过的东西
真正。不幸的是,它也是有史以来最(恶意)滥用编程引用之一。由于Donald Knuth创造了模因,因此有必要在报价中添加一些原始内容:
我们应该忘记效率低下的问题,例如大约97%的时间:过早的优化是万恶之源。但是,我们不应该放弃那临界的3%的机会。……优秀的程序员……明智地仔细看待关键代码;但只有在识别出该代码之后。...一直使用测量工具的程序员的普遍经验是,他们的直觉猜测会失败
注意,Knuth特别讨论了运行时的执行速度。
..程序员浪费大量时间来思考或担心程序非关键部分的速度。
另外,他在1974年写了这篇文章,当时任何机器资源在执行速度和程序的可维护性(更高的速度-更少可维护性)之间处于溢价和负相关关系时,都可能比现在更强大。
好的,要回答您的问题,根据Donald Knuth的说法,如果优化能够解决已发现的严重性能瓶颈(在性能分析过程中进行理想地测量和确定),则优化还为时过早。
正如我之前所说,“过早优化”是最恶意滥用的模因之一,因此,如果没有一些不是过早优化但有时会被忽略的事情的例子,答案将是不完整的:
甚至与运行时执行的速度都没有关系:
周到的前期设计
静态输入(!)
等/任何形式的精神努力