当前位置:  开发笔记 > 编程语言 > 正文

什么时候优化过早?

如何解决《什么时候优化过早?》经验,为你挑选了9个好方法。

正如Knuth所说,

我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源.

这是Stack Overflow常常出现的问题,例如"哪个是最有效的循环机制","SQL优化技术?"等问题.(等等).这些优化提示问题的标准答案是分析您的代码并首先查看它是否是一个问题,如果不是,那么您的新技术就不再需要了.

我的问题是,如果某种技术不同但不是特别模糊或混淆,那真的可以被认为是过早的优化吗?

这是Randall Hyde的一篇名为"过早优化的谬误"的相关文章.



1> Norman Ramse..:

Don Knuth开始了文学编程运动,因为他相信计算机代码最重要的功能是将程序员的意图传达给人类读者.任何使代码难以理解的编码实践都是过早的优化.

以优化的名义引入的某些习语已经变得如此受欢迎,以至于每个人都理解它们并且它们已经成为预期,而不是为时过早.例子包括

在C中使用指针运算而不是数组表示法,包括使用这样的习语

for (p = q; p < lim; p++)

将全局变量重新绑定到 Lua中的局部变量,如

local table, io, string, math
    = table, io, string, math

除了这些成语之外,走捷径也是危险的.

除非,所有优化都是不成熟的

程序太慢(许多人忘记了这一部分).

您有一个测量(配置文件或类似),表明优化可以改善一些事情.

(也可以优化内存.)

直接回答问题:

如果你的"不同"技术使程序更难理解,那么这是一个过早的优化.


编辑:在回应评论时,使用quicksort而不是像插入排序这样的简单算法每个人都理解和期望的成语的另一个例子.(虽然如果你写了自己的排序例程,而不是使用库排序例程中,人们希望你有一个非常好的理由.)


根据你的定义; 如果快速排序实现比bubbleort更难阅读和理解,那么这是一个过早的优化.你不能优化内存?尝试查找大型稀疏矩阵的相同示例.恕我直言,大多数优化应该在设计阶段进行.我很早就开始了.
任何排序算法,包括你发明的算法,如果用单独的函数sortQuickly(...)编写并带有适当的注释,则清晰简洁.
@Norman:虽然快速排序现在*无处不在,但它不是第一次发明时,因此QED过早优化,作者没有业务搞乱,对吧?
@Software Monkey:绝对.所有CS研究都是浪费纳税人的钱,应该立即停止.

2> SmacL..:

恕我直言,90%的优化应该在设计阶段进行,基于所需的电流,更重要的是,未来的要求.如果你必须拿出一个分析器,因为你的应用程序没有扩展到所需的负载你就已经太迟了,IMO将浪费大量的时间和精力而无法解决问题.

通常,唯一值得的优化是那些能够在速度或存储或带宽乘数方面提高数量级性能的优化.这些类型的优化通常与算法选择和存储策略有关,并且极难逆转到现有代码中.它们可能会影响您对实现系统的语言的决策.

所以我的建议是,根据您的要求提前进行优化,而不是根据您的代码进行优化,并考虑应用程序的可能延长寿命.


根据我的经验,我同意"当你需要分析器时,它已经很晚了" - 我的大多数性能问题不是单一的瓶颈,而是分散在多个贡献者身上.但是,我在低级代码和成本方面有很强的背景,并且本能地避开任何依赖(重复)删除第一个字符串字符的任何符号.+1表示"在设计时优化".
我不同意你的"太晚了"的结论.当假设不成立时,基本上需要进行分析,并且需要分析器来告诉您WHAT假设已经破坏.例如,我发现Java中StringBuffers的"删除位置0处的字符"对于junit测试工作正常,但对于大字符串来说非常慢.在剖析器指出它是罪魁祸首之前,我没有怀疑代码!
+1"过早意味着你没有及早做到这一点"

3> JaredPar..:

如果您还没有进行过分析,那就太早了.


我同意它背后的想法,但是:除非实现完全受CPU周期的约束,否则获得既可重复又可以推广的测量很难 - 而且它越稳定,它就越不现实.
我不同意.Knuth谈论的是效率低下.优化通常发生在设计阶段.它涉及选择适当的数据结构和算法,这些数据结构和算法通常会产生很大的性能影响,并且不一定能在以后进行交换.

4> Shog9..:

我的问题是,如果某种技术不同但不是特别模糊或混淆,那真的可以被认为是过早的优化吗?

嗯......所以你手头有两种技术,成本相同(使用,阅读,修改同样的努力),一种更有效.不,在这种情况下,使用效率更高的人不会为时过早.

中断你的代码编写,寻找常见的编程结构/库例程的替代方案,尽管有一个更有效的版本挂在某处,即使你知道所写的相对速度永远不会真正重要. .. 那是不成熟的.


同意,如果你知道一种算法对你的用例更有效,那么一定要使用效率更高的算法.如果您不知道最有效的算法,请使用您拥有的内容并稍后进行配置文件以查看是否存在问题.

5> Mike Dunlave..:

这是我在避免过早优化的整个概念中看到的问题.

说出来与做之间存在脱节.

我已经做了很多性能调整,从其他设计良好的代码中挤出了大量因素,似乎没有过早优化. 这是一个例子.

在几乎每种情况下,性能欠佳的原因都是我称之为奔腾的通用性,即使用抽象的多层类和彻底的面向对象设计,其中简单的概念不那么优雅但完全足够.

在教授这些抽象设计概念的教材中,例如通知驱动的体系结构,以及信息隐藏,只需设置对象的布尔属性就可以产生无限的连锁反应效果,给出的原因是什么?效率.

那么,是不是过早优化?



6> Vatine..:

首先,让代码工作.其次,验证代码是否正确.第三,快点.

在阶段#3之前完成的任何代码更改肯定为时过早.我不完全确定如何对之前做出的设计选择进行分类(比如使用非常适合的数据结构),但我更愿意转向使用抽象方法,而不是那些表现良好的人,直到我在我可以开始使用分析并具有正确(但通常很慢)的参考实现来比较结果的阶段.



7> FredV..:

你似乎在谈论的是优化,比如使用基于散列的查找容器与像数组一样的索引容器,当进行大量的键查找时.这不是过早的优化,而是您应该在设计阶段决定的事情.

Knuth规则的优化类型是最小化最常见代码路径的长度,优化最常运行的代码,例如在汇编中重写或简化代码,使其不那么通用.但是,在确定代码的哪些部分需要这种优化并且优化意愿(可能?)使代码更难理解或维护之前,这样做是没有用的,因此"过早优化是所有邪恶的根源".

Knuth还说,改变程序使用的算法,而不是优化,总是更好,这是解决问题的方法.例如,稍微调整可能会使优化速度提高10%,从根本上改变程序的工作方式可能会使速度提高10倍.

针对这个问题上发表的很多其他评论做出反应:算法选择!=优化



8> HLGEM..:

从数据库的角度来看,在设计阶段不考虑优化设计充其量是蛮干的.数据库不容易重构.一旦它们的设计很糟糕(这就是一个不考虑优化的设计,无论你怎么试图隐藏在过早优化的废话之后),几乎永远无法从那恢复,因为数据库太基础了整个系统的运作.考虑到您期望的情况的最佳代码,而不是等到有一百万用户并且人们尖叫,因为您在整个应用程序中使用游标,正确设计成本要低得多.其他优化,例如使用可搜索代码,选择看起来最好的索引等等,只有在设计时才有意义.有一个原因可以称之为快速和肮脏.因为它不能很好地工作,所以不要使用快速作为良好代码的替代品.坦率地说,当您了解数据库中的性能调优时,您可以编写更有可能在同一时间内执行良好的代码,或者编写代码执行效果不佳的代码.没花时间去学习什么是性能良好的数据库设计是开发人员的懒惰,而不是最佳实践.



9> yfeldblum..:

格言的要点是,通常,优化是复杂的和复杂的.而通常,你建筑师/设计师/程序员/维护者需要清晰,简洁的代码,以便了解正在发生的事情.

如果特定的优化是清晰简洁的,请随意尝试(但请返回并检查优化是否有效).重点是在整个开发过程中保持代码清晰简洁,直到性能的好处超过编写和维护优化的诱导成本.


实际上,很多“优化”归结为为工作选择合适的算法。这是一项具有高水平成果的高水平活动,与Knuth报价中的“低效率”相去甚远。
推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有