我总是要考虑性能吗?

时间:2009-01-22 23:41:51

标签: performance optimization

我来自DBA世界,表演一直是一种痴迷。我正在转向发展,我总是不断地考虑绩效。

阅读SO有时似乎表现并不重要。例如,对于休眠(或任何其他ORM)的福音传道者。

作为开发人员,我什么时候需要考虑性能?何时不考虑?

21 个答案:

答案 0 :(得分:17)

一般来说,对性能或优化的迷恋是软件开发中的恶劣之路。通常,只有大约5%(或更少!)的代码对整个系统的性能有任何影响。您的主要目标,首先是作为大多数项目的软件开发人员,正在获得正确可靠的功能,当然还有系统的可维护性。然后,一旦实施并正常工作,您就可以评估性能,找出瓶颈所在,并相应地对其进行优化,以实现您的总体目标。

一个警告 :对事物采取的O(n)类型评估是事先考虑的合理事项,作为原始系统设计和算法选择的一部分等等,只是为了感到自信,表演将“在球场”。但除此之外,大多数在实际测量瓶颈所在之前优化事物的尝试将导致优化无关紧要的事情,并且通常会使事情变得难以维护,难以理解等等。

答案 1 :(得分:13)

Knuth quote(“我们应该忘记效率低,大约97%的时间:过早优化是所有邪恶的根源”)可能适用。

当你开车时,你是否经常有意识地检查你的汽车与路边的距离?如果你有足够的驾驶经验,你就会知道它的边缘在哪里以及大致如何驾驶和停放它而不会碰到附近的东西。

类似的编程表现的直觉/经验对于通过试错/问题获得很重要,但你不应该花时间不断地仔细检查自己。

答案 2 :(得分:5)

什么时候?

不,认真。有些应用程序永远不会有足够的用户保证数据库中的基本索引和关键关系。它们不需要调整代码的内部循环。例如,工作组大小的应用程序。

随着规模的扩大,对代码,数据访问和通信方面的优化路径的需求也在增加。如果您正在使用有限的硬件(嵌入式系统),那么您需要关注性能批次。但是,有许多应用程序永远不会看到足够的用户来制作系统资源,甚至会注意到你在那里。

在这些情况下,所有额外的工作都是浪费金钱和精力。在某些情况下,您的规范明确表示您需要额外的努力。在某些情况下,它会明确你永远不会

答案 3 :(得分:5)

我认为这里有两个相互矛盾的谚语。

1:过早优化是万恶之源。

2:在你跳跃之前先看看。

根据我的个人经验,情况就是这样,当代码首次编写时,很容易找到使用90%资源的3%代码查找魔法的可能性。这是第一个谚语相关的地方,似乎产生了很好的结果。然而,随着代码库的成熟,似乎使用90%的资源而不是3%,你突然有50%使用90%的资源。如果你想象一下水管的类比,而不是几个大的泄漏,你现在有了多个小泄漏的问题,到处都是。这使整个应用程序的性能降低,即使很难确定任何一个单独的功能。

这是谚语2似乎相关的地方。不要依赖第一句谚语,不做任何绩效计划,制定整体计划,即使它是一个不断发展的计划。尝试制定一些可接受的性能指标并计划您的计划。考虑设计选择的后期性能影响。例如,如果需要的只是一个元组存储,那么可能会提前使用元组存储而不是数据库。从SQL数据库开始,然后在以后更改为元组存储是非常困难的。

最重要的是,尽量优化其易用性,并对可能进行优化的案例做出说明。如果你不这样做,随着时间的推移,程序往往会遭受一千次削减的死亡,因为功能的影响比他们需要加起来的速度快5-20%并且确实会成倍增加。

答案 4 :(得分:5)

引用Knuth的“过早优化......邪恶”是编写草率和慢速代码(正确或其他)的不良论据。

  1. 您需要指标进行优化。
  2. 编码时需要考虑代码。
  3. 您只需优化重要的代码子集。
  4. 如果您正在编写一个简单的表单来更新某些细节,那么可能不值得优化。

    如果您正在撰写谷歌搜索引擎替代品,并且您希望拥有大量流量,那么您可以找到一种尽可能快地进行搜索的方法。

    你只需要优化重要的代码,并且程序中有很多代码用于执行一次性事务或很少发生的事件。


    鉴于我们满足上述1,2和3:

    在进行任何性能测试和优化之前,等待应用程序完成90%是没有意义的。性能通常是不成功的非功能性要求。您需要识别并记下其中一些不成文的要求并将其提交给他们。

    如果您需要进行架构或其他重大更改,那么完成90%也可能为时已晚。编写的代码越多,改变事物就越难,只要考虑到需要考虑的代码。您需要不断确保您的应用程序能够在需要的时间和地点执行。

    然后,如果你有完善的单元测试,你应该能够将性能测试作为这些测试的一部分。

    至少我的2先令。

答案 5 :(得分:4)

我有一个阶段,我对性能绝对偏执。我花了很多时间来提高性能,而我的代码从未实际发展过。不要养成这种习惯: - )

代码,那么优化,而不是同时优化。

答案 6 :(得分:3)

  

性能不是可以的   在项目结束时粘贴。

答案 7 :(得分:2)

在您正确运行之前,请不要考虑性能。如果它正常工作,并且没有任何用户明显的性能问题,请不要优化。

如果它正常工作并且有明显且明显的延迟,不会优化。简介而不是。大多数应用程序的时间将花费在一个“热”循环中,而它的循环很少是直观的。你需要真正的测量和科学来告诉你发生了什么。获得个人资料数据后,您的优化任务应该从大到小:

  1. 架构优化。应用程序的整体结构是否是无效的来源?

  2. 算法优化:您使用的是正确的数据结构吗?你是以正确的方式访问它们吗?您的应用程序是否大部分时间都在写作,或者大部分时间是在阅读?优化该问题的答案。

  3. 最后的手段。 Microoptimization。简化热循环,或展开一些循环。达夫的装置。在您确定不能对其他两个级别进行进一步改进之前,不要在此级别进行优化,并且仍然没有达到您的性能目标。这种优化水平很可能会破坏狗屎,使你的应用程序更难以增长,更脆弱,所以除非你真的需要,否则不要这样做。

  4. 我再次强调,不要浪费你的时间优化任何看起来效率低下的随机代码。优化时间是一项重大投资。在赌博失败者之前,你应该有证据支持你。

答案 8 :(得分:1)

您应该在构建应用程序之后优化性能,并且只有在您有瓶颈证据的情况下才能进行优化。 (例如,通过分析)也许你发现没有必要进行优化,特别是因为编译器通常比你好得多。

答案 9 :(得分:0)

我在某种程度上不同意这个方面。

你总是考虑表现 - 但这种考虑通常是为了解雇它。看看代码运行的频率。如果答案是“一次”或“很少”,那么表现基本上不是问题。

只有当一段代码要经常执行时,您才需要注意性能。即使在这种情况下,通常也应该只查看例程的O()类,直到分析显示出问题。

在我最初编写时,我唯一会考虑详细优化的内容是O(可怕)例程中的代码。 (示例:确保一组数据不包含死角的测试.O(n ^ 8),虽然进行了大量修剪。我从第一行开始就注意了性能。)

答案 10 :(得分:0)

答案 11 :(得分:0)

不,如果您要考虑某些事情,那么考虑为您的雇主/客户和客户提供价值。想想对他们来说重要的是什么。

尽管如此,性能 很重要,但它可能导致毁灭。

“战争黎明2”于2月发布了一款破坏多人游戏的破坏游戏的游戏。问题?人口上限。当一个小队被重新强制执行时,由于编码错误,最后一个单位占用了两倍的上限。这意味着您可能处于一个非常小的军队的情况下,当您尝试创建一个新单位时,游戏会告诉您场上有太多单位。最令人沮丧的。

为什么这是一个问题?这怎么可能只是在重新执行时出现的问题?如果只是购买该装置是一个问题,那么肯定会在测试中发现它!

我的猜测是,这是由于过早优化。当你点击“购买单位”按钮而不是像银行那样制作pop-cap时,开发人员不想预先考虑所有单位,所以当创建一个单位时,它会从银行取出帽子,当它死亡时,弹出帽子被放置回到银行。当然,这是更高效的,但一个小错误会使整个银行失去一步。

更糟糕的是,当你在Dow2论坛上按下“购买单位”按钮或大量火焰时,一个小小的打击,愤怒的客户和MS拖延认证修复意味着它尚未修复?

在很多情况下,最好标记

// todo: performance could be better
// try doing xyz if we need to improve it

因为性能版本需要更多时间并且会增加代码的维护成本。

您应该担心的表现是为您的客户提供满意的并满足他们需求的解决方案。到达发布日期的速度通常更为重要。

在某些情况下,一般性能很重要,例如嵌入式系统,但这应该被称为预先限制,并且是在您点击代码之前应该注意的特殊上下文。

答案 12 :(得分:0)

最好编写代码,然后确定最有利于优化的关键区域。

有时代码会被替换,删除或重构。优化太多代码可能会浪费宝贵的时间。

答案 13 :(得分:0)

您希望考虑有关特定问题的效果,因为您可能需要在某一天处理每个问题的性能问题。

含义 - 如果它不会得到大量使用,请相应地担心。不要太懒惰或低效,并且不要过分迷恋每次获得算法的必杀技。通常最好编写最简单的代码,并根据需要使其更快/更优化。与此同时,任何开发人员都可以使用简单的代码,这是值得考虑的事情。

如果你看到它的重要性在增加,现在你知道要考虑更多,因为它会在后面咬你。

作为开发人员,我们有一个想要完美的v1.0的问题。工作的v1.0是有效的,不适合未来可能带来的每一种情况。

对我而言,一个很好的例子是多年前我开始使用数据库。当查询无法想象地放慢速度时,我不知道还有哪些额外的索引或者它们提供的出色性能提升。

我们无法预测每一个问题。我试着做好设计,让问题争取我的注意力。

希望有用的东西。

答案 14 :(得分:0)

回答1:

许多人正确地说“不要考虑性能,稍后进行优化”,但要记住他们有单元测试。他们可以重写代码库的大部分而不用担心会引入错误。如果你在没有任何单元测试的情况下重写,你必须手动测试的所有内容,这次更难,因为算法更复杂。

可以推迟优化直到稍后,但你必须确保你已做好准备。如果你没有一个可行的后期优化计划(单元测试,用于分析代码的工具),那么你最好现在考虑一下性能,因为它会在以后更多地伤害你。

回答2:

有时,您首先提出的简单工作解决方案会在O(n^n)时间运行。如果您知道,您将拥有大量数据集,请立即进行优化。

回答3:

前一段时间,我厌倦了PHP中的瑕疵并尝试修复其中的一部分。我写了一个框架,其中涉及所有必须继承的基类。它使用方法和属性重载,反射以及几乎所有其他高级功能来使其工作。然后我继续使用我自己的框架功能而不是isset()static等基本语言功能,在一个大型项目中使用它。该项目的代码更加整洁,但魔术减慢了每个方法调用,并且属性访问速度提高了大约50倍。

如果您要尝试扩展语言本身,您需要考虑性能现在,因为如果不能,您必须重新编写所有内容优化它。 C拥有零成本的宏观系统,适合您的生活。 Javascript没有这样的系统,在编写想要在任何地方使用的新对象继承系统时要非常小心。

答案 15 :(得分:0)

通常归结为要求。在某些情况下,您对响应时间等有非常严格的非功能性要求。在这些情况下,您应该额外努力调整代码,程序等。

但是作为经验法则(恕我直言),您应该根据可靠性和可维护性的最佳实践构建代码,然后围绕性能进行特定的测试。这样,您就会知道只会调整实际影响性能的代码。

答案 16 :(得分:0)

像其他人说的那样,在你知道问题之前进行优化是浪费时间。我最近研究了一些经过大量优化的代码,而且我的大部分时间用于删除优化!问题是它使得添加关键功能变得不可能。

另一个例子......在我之前的工作中,我在数据处理工作,编写围绕可执行程序的脚本。如果我在晚上5点开始一个程序,并在第二天早上8点结束,那就足够了。当然,在紧急情况下,它需要花费一个小时而不是十个更好,更快的代码使我的工作变得更容易,但只要它正确运行 30分钟相当于16小时。

这完全取决于您的项目......应该考虑您的项目要求。

还要记住,使程序更高效需要更长的时间......你正在以快速的速度开发执行速度。

答案 17 :(得分:0)

我发现通过开发单位的典型模式是:

  1. 将从头到尾通过主要用例工作的最小版本放在一起。在这一步中,我主要关注简单性和适用于任何模式的良好实现。

  2. 第2步是重构步骤1,主要是为了简化。由于我一直在做OOP,我似乎能够依靠的一件事是,这一步总是呈现出许多明显的简化和实际的代码减少。这也是显而易见的抽象失效的原因(这是另一种简化。)重要说明:这对解决性能有很强的次要影响,特别是当你已经完成几次并且你知道高性能反模式的位置时。 / p>

  3. 通常,当#2完成时,事情的表现令人满意,但测试会证实这一点与否;并指出需要解决优化的(通常很少)位置。

  4. 我越来越多地看到,无论何时我在第1阶段和第2阶段考虑高效设计,都会让人觉得简单,这在当时是主要的。

答案 18 :(得分:0)

我正致力于构建搜索引擎。优化是使用户继续搜索或离开网站之间的差异的原因。我认为许多应用都是如此,不幸的是,他们中的许多人并不关心它。有时在问题上投入更多硬件要便宜得多。不幸的是后者更容易。总而言之,我要说你必须在需要处理大量数据和/或快速处理数据时进行优化。

答案 19 :(得分:0)

对我来说,当我处理图像处理,多个大型SQL查询或循环通过100k标记时,我考虑优化。否则我不这样做,除非我看到它的工作速度很慢。

答案 20 :(得分:0)

  

我何时需要考虑表现,何时不考虑?

无论何时考虑正确性,都可以考虑性能。 : - )

大多数情况下,你的想法是“这个位的表现无关紧要:因为即使这个位,整个应用程序的性能仍然不错,或者因为与其他位的成本相比,这个位的成本可以忽略不计或无限小。“