优化有多重要?

时间:2009-04-02 15:37:17

标签: optimization

我昨天和老板讨论了在构建软件时优化的正确作用。从本质上讲,他的立场是优化需要成为整个开发过程中的主要关注点。

我的观点是你需要在开发过程中做出正确的算法决策,但你永远不应该在开发过程中计算周期。事实上,我对此感到非常强烈,我不得不离开谈话。我在“优化”的名义下看到了太多错误的编程决策,并且以“这种方式更快”为借口辩护了太多糟糕的代码。

StackOverflow.com社区的想法是什么?

14 个答案:

答案 0 :(得分:25)

  

“我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源。但我们不应该放弃我们在那个关键的3%中的机会。”

- 唐纳德克努特

答案 1 :(得分:15)

我认为过早的优化引用被太多用来避免考虑关于应用程序运行情况的难题。我保证用户希望您考虑如何设计它,以便尽可能快地运行。

这并不是说你应该对所有东西进行计时,但设计阶段是最容易优化的地方,而不是花费大量时间。

通常有几种方法可以做任何事情,你应该在设计阶段选择最有可能表现最佳的方法(如果结果是不是最好的时候之一,那么优化后来)。这应该胜过需要易于阅读的代码。

如果您不在设计阶段考虑性能,那么您将无法拥有设计良好的系统。这并不意味着它应该是唯一的问题(尽管在数据库中我将​​其评为重要性的第3位,就在数据完整性和安全性之后),但是试图修复一个系统,其中整个过程中使用性能较差的技术因为开发人员以为他们更容易理解是一场噩梦。作为这样一个系统的用户,每次你想要从一个屏幕移动到另一个屏幕时你必须等待几分钟是一场噩梦(开发人员应该每天花一整天时间,至少一周,使用他们的系统!)给每个人坚持设计糟糕的系统。它的设计成本要低于以后修复的成本,并且考虑到性能对于正确设计至关重要。

我工作的地方是原始开发人员在过早优化方面喝了koolaid并按照他们认为最简单的方式做了所有事情(但从性能角度来看几乎在每种情况下都是错误的选择)。现在我们的规模是三年前的10倍,每个网站上的每个屏幕都需要30秒左右才能加载(或更糟糕的时候),因此我们正在失去客户。但改变它将太难了,因为在基础上他们设计了数据库而没有考虑它将如何执行和重新设计具有许多千兆字节的数据到新结构的数据库是太耗时和昂贵。如果它从一开始就被设计为执行,那么对于客户来说,它将更容易维护和更快。我们并没有谈到在这里调整前10个最慢查询的性能需求,我们正在讨论这样一个事实,即整体结构需要进行大幅度的改变(几乎会影响对系统的每个查询)才能表现良好。

是的,不要做微观优化,直到你知道,但请做宏观的东西。在提交路径之前,请考虑这是否是最好的方法。当基于集合的语句执行时,不要编写游标来命中具有数百万条记录的表。不要试图拥有尽可能少的表,因为当表存储不同的项目(例如人,地点和车辆)时,似乎是一个更优雅的解决方案,导致每个查询都命中同一个表并导致每次删除检查那些永远不会有该类型实体记录的各种外键表(从我们数据库的主表中删除一条记录需要几分钟,当导入中出现问题时,这是一个真正的乐趣(坏数据)通常来自客户)我们必须删除200,000让我告诉你)。

答案 2 :(得分:8)

优化几乎是同义反复的权衡:以其他东西为代价获得运行时效率(可读性,可维护性,灵活性,编译时间等)。因此,除非你知道什么是权衡以及为什么值得这样做,否则这绝不是一个好主意。

更糟糕的是,考虑“我如何快速做X”可能会让人分心。在这个方向上的大量能量很容易导致你对方法Y的误解更好(并且通常更快 - 这就是“优化”可以使你的代码变慢的方式)。特别是如果你从一开始就在一个大项目上做太多这样的事情,那就代表了很多动力。如果你无法克服这种势头,你很容易陷入糟糕的设计,因为你没有时间重组它。这种方式就是龙子

您的老板可能会想到的更多是通过不恰当的表示和算法编写错误代码的问题。它与优化并不是一回事,但是一种你不关注适当的数据结构等的方法会导致代码库在任何地方都很慢,而且(就像上面的“锁定”一样)需要英雄的努力来解决

总的来说,过早的优化确实是一个可怕的想法。特别是当你最终得到一个复杂的,精心调整的,有文档记录的(因为这是你能理解它的唯一方法)时,你最终还是没有使用这些代码。而这甚至没有涉及“优化”

时经常引入的微妙错误的问题

[编辑:pshaw,当然Knuth引用很好地封装了这个。这就是我输入太多的东西]

答案 3 :(得分:5)

全程工程师,最后进行优化。

答案 4 :(得分:3)

由于精简,我会说优化与不做的影响一样重要。

答案 5 :(得分:3)

我认为“过早的优化是所有邪恶的根源”必须从字面上理解 - 它没有说什么时候为时过早,并且没有说你应该只在最后进行优化。只是不要太早。此外,“使用正确的算法,O(n ^ 2)vs O(N)”如果按字面意思理解有点危险 - 因为对于许多问题,N实际上很小,等等......

我认为这取决于你正在做的很多软件类型:某些软件是如此,每个部分都非常独立,并且可以单独进行优化。但情况并非总是如此。对于许多(大多数?)应用程序来说,速度根本不重要,蛮力但明显正确的方式是最好的。但对于速度很重要的项目,通常必须尽早考虑 - 也许这是对Knuth说的另一种可能的解释:许多应用程序根本不需要进行优化,只需知道哪些应用程序需要并提前计划。

答案 6 :(得分:3)

如果优化是次要问题,那么当您有充分的理由预期性能将无法解决时,优化是开发过程中的主要问题。

这很大程度上取决于您编写的代码类型,但通常有更好的理由相信您的代码将难以使用;或保持;或者充满了虫子;或迟到;如果所有这些都成为调整性能的第二步。

糟糕的经理人说,“所有这些都是我们的主要关注点”。优秀的管理者努力找出这个项目的危险性。

当然,优秀的设计必须考虑所有这些事情,并且越早对其中任何一个进行背面估计越好。如果您的所有经理都在说,如果您从未考虑过您的代码运行速度有多快,那么您的代码过多会慢得多,那么他就是对的。我只是不会说这使得优化成为您的“主要”问题。

如果您的软件的USP比竞争对手的速度快,那么优化是首要考虑因素。根据经验,您通常可以预测哪些类型的操作将成为瓶颈,从一开始就考虑优化设计,并在其他地方或多或少地忽略优化。许多项目甚至不需要这样:只要你使用合理的算法并且不做任何愚蠢的事情,它们就会足够快速而不费力。 “不要做任何愚蠢的事情”始终是一个主要问题,特别是不需要提及表现。

答案 7 :(得分:1)

我认为代码首先必须是可读和可理解的。因此,完成的优化不应以牺牲可读性为代价。但是,优化往往是一种权衡。

是否应该优化代码取决于您的应用程序域。如果您正在使用只有8Mb内存的嵌入式处理器,那么在编写代码时,优化可能是每个团队成员需要记住的 - 优化空间与速度。

然而,除非您的系统已经明确规范和理解,否则预成熟优化是没有用的。这是因为大多数程序员不会做出好的优化决策,除非他们可以考虑整个系统的影响,包括处理器架构因素,如高速缓存,硬件线程,管道等。

答案 8 :(得分:1)

从构建高度优化的Java代码2年开始(以及需要以这种方式进行优化)我会说有一个耗费时间的规则来管理优化:

  • 现场优化:5%-10%的开发时间,因为你必须无数次(每次都需要修改你的设计)
  • 优化工作时间:2%的开发时间(仅执行一次)
  • 回到它并优化它的速度太慢:30%的开发时间,因为你必须重新投入系统

所以我得出的结论是,有一个正确的时间和正确的优化方式:按实体逐个实施(按类分类,如果你有一个具有单一,定义明确的工作的类,并且可以进行测试和优化),测试好,确保逻辑正常工作,然后进行优化,并永远忘记该实体的实现细节。

答案 9 :(得分:1)

  1. 开发时,只需保持简单即可。恕我直言,大多数性能问题都是由于过度工程造成的 - 通常是因为想要“正确的算法”而使山脉不受影响。

  2. 定期进行压力测试,使用大数据集,剖析或(我最喜欢的技术)手动随机抽样。你找到了问题,你解决了。你找到另一个,你解决它。

  3. 这样你就可以避免创建slug(慢速错误),当它们出现时,你会杀死它们。

    补充说:如果我可以详细说明第1点。面向对象似乎是土地的法则,它背后肯定有充分的理由。不幸的是,它让许多年轻的程序员感到编程就是拥有大量的数据结构,层次上是抽象的。并不是说那些本质上是坏的,而是将它与自然倾向相结合,假设所花费的时间大致与你要调用它的字符数量成正比,并且这种趋势在层上倍增(此外,机器真的很快),很容易创造一个完美的循环浪费风暴。

答案 10 :(得分:1)

来自朋友的话:“制作一个高效的系统工作系统比制作高效系统更容易”。

我认为从一开始就使用智能实践和模式很重要,但要让系统实际运行小型测试用例,然后进行性能分析。通常情况下,性能较差的代码区域在开始时不会被预期,因此获取一些实际数据然后优化瓶颈3%(或20%,或者不管它是什么)。

答案 11 :(得分:1)

我认为你的老板比你更好。

经常失去用户体验只是为了在性能活动过于昂贵和低效的最后可能时刻被“重新发现”。或者,当发现将处理今天的交易的批处理程序需要运行40个小时时。

诸如数据库组织之类的事情,何时何时不执行哪些SELECT是可以创建或破坏应用程序的设计决策的示例。仍然存在一个程序员决定否定,误解或根本不理解该做什么的风险。在整个项目期间对绩效进行跟踪可以降低发生此类事情的风险。它还允许在需要时更改设计决策,而不会使整个项目处于风险之中。

“你需要在开发过程中做出正确的算法决策”当然有多少主流程序员能够做到这一点?浏览网络以获取信息并不能保证找到高质量的解决方案。 “正确”可以解释为选择差算法是可以的,因为它比较复杂的算法(=更少的开发时间,更高的成本)更容易理解和实现(=更少的开发时间,更低的成本)。 / p>

数量与质量的钟摆几乎总是在数量方面,因为每小时更多的代码或更快的开发时间意味着短期内的货币。质量方面意味着长期的资金。

修改

This article非常彻底地讨论了性能和优化。

表演传道人Rico Mariana sums it up在简短陈述中“从不会意外放弃你的表现。”

答案 12 :(得分:0)

过早优化是所有邪恶的根源......两者之间有一个很好的平衡,但我会说95%的时间你需要在最后进行优化;但是,您可以尽早做出决定以帮助预防问题。例如,假设我们正在讨论电子商务网站。您需要显示目录。现在,您可以抓取所有100,000个项目并显示其中的50个,或者您只能从数据库中获取50个项目。这些决定应该在前面做出。

只有在发现问题后才能进行周期计数。

答案 13 :(得分:0)

您的老板部分正确,在整个开发生命周期中需要考虑优化,但这很少是主要关注点。此外,“优化”一词含糊不清 - 它是一个形容词,“优化......”,可以是“记忆”,“速度”,“可用性”,“可维护性”等。

然而,OP对于许多项目来说计数周期毫无意义是正确的。对于大多数PC应用程序而言,CPU永远不是瓶颈。此外,IA32并不一致 - 在一个架构上运行良好,在另一个架构上表现不佳。只有当它实际上有所作为时才应该进行周期计数 - 通常是在CPU限制的代码或具有非常特定时序需求的代码中。

任何类型的优化必须始终由确凿的证据驱动。永远不要假设有关系统或代码的行为方式。在理想的世界中,应用程序性能/约束将在初始产品设计中指定,并且将在开发阶段的早期添加用于监视应用程序在开发期间的性能的工具,以指导程序员在产品制作过程中。