规划效率早期与过早优化

时间:2009-02-05 14:38:54

标签: language-agnostic optimization

我似乎注意到在优化方面出现了两种思想:

  1. 过早优化是万恶之源。您应该只在编写最可读和最简单的东西时进行优化。如果在分析后确定软件太慢,则应进行优化。
  2. 优化应该在项目的生命周期早期完成。需要对优化进行规划,但应该合理地进行。
  3. 从表面上看,他们似乎是相当反对的观点。问题是,我看到了两种思想流派的优点。我还可以想到,这两种思维方式都有助于我编写更好,更快的软件。

    有没有办法调和这两个想法?有中间地带吗?是否有时候一个想法是这项工作的最佳工具?或者我是否提出了错误的二分法,这两种观点可以和平共存?

14 个答案:

答案 0 :(得分:27)

尽早优化设计和架构层面。稍后在实施级别进行微优化。

您需要了解您所做的设计决策的性能成本,以后将难以更改。实施通常可以在以后进行调整,这就是为什么在您知道这是一个问题之前不值得这样做。

答案 1 :(得分:9)

我通常做的是应用那些不花费我任何成本(或几乎没有)的优化。我也一直在寻找那些不能很好地扩展并且经常调用的算法。除此之外,我不会优化,直到软件运行,我有机会启动探查器。只有这样,我才会投入一些时间进行优化。

答案 2 :(得分:4)

专注于编写完全符合预期要求的代码,并且只需要编写所需的次数。优化干净,优雅的代码通常很简单。

答案 3 :(得分:4)

理想情况是首先进行剖析,然后在必要时进行优化,但这不适用于设计;当你有任何可执行文件来分析时,改变设计将是非常昂贵的。因此,设计必须注重效率。通常这意味着预先勾勒出有效的算法,并保持足够的灵活性以便以后更改。 (这通常最好通过良好的功能分离,尽可能保持模块独立,这是出于其他原因的良好设计实践。)

通常,在设计阶段,您会很清楚性能的重要性。如果需要,您可以从一开始就设计性能(不包括代码级优化)。

在两种类似的实践之间进行选择时,也开发了有效的编码习惯。例如,在C ++中,输入++i而不是i++是值得的,因为它有时可以显着提高效率。

除此之外的任何事情应该等到(a)很明显,提高性能会得到回报,(b)你知道热点在哪里。

答案 4 :(得分:3)

调整引用“如果你赢了就是它的策略,如果你输了则是作弊”,我会说

  

如果它有效,那就是“效率计划”,如果没有,那就是“过早优化”。

答案 5 :(得分:2)

我喜欢this guy的表述。

  
      
  1. 使用更多优化   明智的整体方法。
  2.   
  3. 通过减少代码来优化   奇怪的。
  4.   
  5. 通过制作优化   代码更奇怪。
  6.   

前两个是你指出2.他的3是你的1,是所有邪恶的根源。而且他是对的,使代码“更加奇怪”的优化使其变得更复杂,更难以理解,从而导致更多错误和维护问题。

答案 6 :(得分:2)

我也有:从一开始就使用适当且高效的数据结构。这涵盖了很多方面:

  1. 了解所有标准容器的工作原理,他们擅长什么以及他们擅长什么。例如。 SortedDictionary可以快速插入和搜索,但删除效果很差。 LinkedList可以快速添加和删除,但搜索效果不佳等等。
  2. 知道瓶颈会在哪里。它是cpu,磁盘,内存,图形,IO,网络等。知道如何有效地利用每一个,每个区域需要不同的设计模式。这实际上取决于正在开发的应用程序 - 关注的核心指标是什么,用于UI响应,以及数据处理良好的磁盘缓存。
  3. Multhreading。如果应用程序将扩展到多个核心,则需要在开发生命周期的早期决定是否需要这样的系统。在稍后阶段进行螺栓螺纹加工的成本要高得多。
  4. 你将从经验中得到一些答案,有些将需要研究,但它永远不会被猜测。

答案 7 :(得分:2)

首次构建它,无需花费大量时间或精力。然后让它争取你的注意力。

答案 8 :(得分:1)

我认为,当你编写代码时,中间立场就是要记住已知的低效率,但如果它意味着在初始开发中增加额外时间或增加复杂性,则不要提前优化。

我的理论是,“编写简单的工作代码,然后根据测试要求进行优化。”

答案 9 :(得分:1)

纯粹应该是投资回报分析。如果您可以花一点时间来设计优化并获得巨大的性能回报,那就去做吧。渐渐地,你将达到努力量的回报不再有意义的程度。

答案 10 :(得分:1)

有一个基本事实:

  

您无法优化无法测试的内容

因此,正如其他人所说,特别是对性能优化,你必须编写代码然后才能测试它。另外,在大量代码中,一种算法可能是通常最快的算法,但考虑到它与其他代码的相互关系,它要么是无用的优化,要么花费你的时间,要么比选项2,3,...慢。 ..

然而,你可以利用一些知识,特别是在概念层面,这可以帮助你在全球范围内“预优化”你的设计。

不幸的是,这是一场没有真正关闭的辩论。

答案 11 :(得分:1)

特别是数据库不容易重构,并且通常是系统中最大的瓶颈,因为设计师认为他们在设计时不应该关心性能。这是短视的。有许多已知的数据库优化几乎在所有时间都会更快。不在设计和初始编码中使用它们以避免“过早优化”是愚蠢的。例如,光标几乎从不(除非您正在寻找运行总计)比SQl Server中基于集合的查询执行得更好。编写游标而不是基于集合的查询并不快(一旦​​理解了基于集合的查询),因此没有理由从基于游标的代码开始。派生表副子查询也是如此。为什么要编写你知道的代码90%的时间比其他需要相同时间写的代码慢?

选择使用一种能够在以后进行性能调整的工具也是一个短视的决定,因此在考虑您打算如何访问数据库时,这应该是您考虑的一部分。

任何对数据库进行编码或设计数据库的人都应该花时间阅读其特定数据库类型的性能调优。事先知道如何写一个可查询的查询以及你应该开始使用哪些索引以及通常的瓶颈类型将有助于你在第一次做得更好。

答案 12 :(得分:1)

这是计划发挥作用的地方。如果你有一个很好的计划并且有一个很好的模型来处理你所写的内容,那么优化只需要在帖子中进行。如果您发现自己需要优化大量代码,那么您最有可能做错了一些事情。

其中很多还会带来经验并从事类似的工作。通常情况下,你唯一需要编写需要优化的东西的时候就是当你覆盖以前从未使用过的东西时。优化发生在IMO的规划阶段和项目后阶段。

答案 13 :(得分:1)

代码除了提供基本功能外,还有三个功能 软件开发人员需要提供:

  1. 性能
  2. 可维护性
  3. 鲁棒性
  4. 空闲代码将提供所有这三个。 在资源有限的情况下,应该优化调用哪部分代码 什么需要评估。 以其他方式为代价优化其中一个是危险的,应该是 尽可能避免。