我是否总是需要考虑性能问题?

18

我来自DBA领域,性能一直是我的追求。现在我转向开发行业,我一直在思考性能问题,时刻关注。

有时在Stack Overflow上阅读,似乎性能并不重要。例如对于Hibernate(或任何其他ORM)的传教士。

作为开发者,什么情况下我需要考虑性能,什么情况下又不需要呢?


2
一个常见的口号是:1)让它工作。2)让它正确地工作。3)然后让它快速工作。当然,以使步骤(3)易于完成的方式设计软件始终是一个好主意。某些类型的软件,例如高性能数学库,将(3)作为基本要求,并需要进行前期设计决策才能实现它,但流程工作流程仍然相同。(1),(2)然后(3)。 - Gilead
实际上,大多数人甚至都没有达到(3),因为在许多情况下,编写的代码通常已经足够快了...而且随着处理器速度每隔几年的提高,你几乎可以免费获得更好的性能(尽管这取决于具体情况)。这也与问题域有关--如果你正在编写会计软件,15%的速度提升不太可能被注意到。如果你正在编写UI库,每一点响应能力的改进都将是一个重大问题。 - Gilead
21个回答

17

总的来说,在软件开发中过于关注性能或优化往往会导致很多问题。通常情况下,你的代码只有大约5%(甚至更少!)对整个系统的性能产生影响。在绝大部分项目中,作为一名软件开发人员,你的首要目标是实现正确可靠的功能,当然还要考虑系统的可维护性。然后,一旦实现并正常工作,就可以评估性能,找出瓶颈所在,并进行相应的优化以达到整体目标。

一个例外:在最初的系统设计和算法选择等方面,进行类似O(n)类型的评估是合理的考虑,仅仅是为了确保性能可以达到预期水平。但除此之外,在实际测量瓶颈所在之前,大多数尝试提前优化的行为都是优化无关紧要的事情,通常会导致代码难以维护、难以理解等问题。


1
这里有一个很大的警告 - 对于1000个项目而言,O(n)处理和O(n!)处理之间的差异可能是10毫秒和宇宙寿命之间的区别。 - Eclipse
@Josh .. 说得对。任何 n < 10 的代码都可能足够快。要知道预期的 n 是多少。写代码时需要思考。 - Robert Paulson

13

这句Knuth的名言(“我们应该忘记小的效率问题,大约有97%的时间:过早优化是万恶之源。”)可能适用于此。

当你开车时,你是否会经常有意识地检查你的车离路缘有多近?如果你有足够的驾车经验,你就会知道它的边缘在哪里,大致上如何驾驶和停车,而不会碰到附近的障碍物。

类似的编程性能直觉/经验通过试错和提问获得是很重要的,但你不应该花费大量的时间去反复检查。


3
汽车的比喻并不恰当。考虑这个:过早优化就像在错误的路线上行驶两倍距离,而维持完美的轮胎气压以优化油耗一样。 - S.Lott
1
当你在附近时,请提醒我离开道路;我同意S. Lott的观点。 - Lawrence Dol
程序员的直觉往往会误判软件问题的根本原因,因此使用分析器来隔离慢速区域。然后编写一个检查单元测试运行时间的程序,并让您的持续集成平台在(重要)测试运行时间过长时通知您。 - Robert Paulson
请不要字面理解!我只是厌倦了每个人都引用“过早优化是不好的!”当很多人对此提出问题时,这些问题都是试图开发一些直觉,以了解如何改善性能的好方法。是的,如果它很重要,应该进行测量。 - Jason S
谢谢你的澄清,Jason。之前并不清楚你的意思。 - Robert Paulson

5

何时需要优化?

不开玩笑。有些应用程序永远不会有足够的用户来证明数据库中的基本索引和关键关系之外还需要更多。它们不需要调整代码内部循环。例如,小型团队应用程序。

随着事物的扩大,对于代码、数据访问和通信的优化路径需求也随之增加。如果您在有限的硬件(嵌入式系统)上工作,您非常关心性能。但是,有许多应用程序永远不会看到足够的用户,使系统资源甚至注意到您的存在。

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


5
我认为这里有两个相互矛盾的谚语与之相关。
1:过早的优化是万恶之源。
2:三思而后行。
根据我的个人经验,当代码首次编写时,很容易找到使用90%资源的神奇3%代码。这就是第一个谚语适用的地方,并且似乎产生了很好的结果。然而,随着代码库的成熟,似乎不是只有3%使用90%的资源,而是突然间有50%使用90%的资源。如果你想象一下水管的比喻,现在你面临的问题是多个小漏洞,遍布各处,导致整个应用程序性能缓慢,即使很难将其归结为任何一个单独的函数。
这就是第二个谚语的适用之处。不要仅仅依靠第一个谚语来进行性能规划,应该有一个总体计划,即使它是一个不断发展的计划。尝试制定一些可接受的性能指标并计时程序。考虑设计选择的后期性能影响。例如,如果只需要元组存储,则可以提前计划使用元组存储而不是数据库。从SQL数据库开始,然后稍后改为元组存储相当困难。
最重要的是,尽量在容易的地方进行优化,并记录可以进行优化的情况。如果不这样做,随着时间的推移,程序往往会遭受千刀万剐的命运,因为比需要慢5-20%的函数的效果会相互累加并且相乘。

5
引用Knuth的“过早优化是万恶之源”并不是写松散和慢代码(无论正确与否)的好理由。
你需要指标来进行优化。
在编码时,你需要考虑代码。
你只需要优化有影响的代码子集。
如果你正在编写一个简单的表单以更新一些详细信息,那么可能不值得优化。
如果你正在编写一个Google搜索引擎替代品,并且你期望有很多流量,那么你需要想办法使搜索尽可能快。
你只需要优化有影响的代码,程序中有很多代码用于做一次性事情或者很少发生的事件。
鉴于我们满足上述1、2、3:
在应用程序完成90%之前等待任何性能测试和优化几乎没有意义。性能通常是未写明的非功能需求。您需要确定并写下其中一些未写明的要求,并承诺遵守这些要求。
如果需要进行架构或其他重大更改,则90%完成时也可能为时已晚。编写的代码越多,改变就越难,即使只是因为有更多的代码需要考虑。您需要不断确保您的应用程序在需要时和地点都能正常运行。
另一方面,如果您有良好编写的单元测试,您应该能够将性能测试作为这些测试的一部分。
至少是我的两个角。

如果可以的话,对于这个回答,我会给你我整个每日的投票配额...我怀疑一般社区因为多年来误解Knuth而受到了太大的伤害,无法为这个回答给予它应得的投票。 - Lawrence Dol
感谢 @Software Monkey .. 我同意你的评估。 - Robert Paulson

4

我曾经有一个阶段,对性能非常担心。我花了很多时间来提高性能,结果我的代码从未真正进步过。不要养成这种习惯 :-)

先编写代码,然后再进行优化,不要同时进行。


3

性能不是项目结束时可以随意添加的东西。


那又怎样,写完代码后就不能再编辑了吗?当然设计不应该太蠢,但是你可以在写完六个月后优化代码。 - Quibblesome
@Quarrelsome:当然可以。这是一个迭代的过程。但是这句话的意思是性能不是你可以在项目生命周期的某个时刻开始设计和实现的“特性”。 - cherouvim

2
在你的代码正确运行之前,不要考虑性能问题。如果它可以正常工作且没有用户明显的性能问题,那就不要进行优化。
如果它可以正常工作但存在明显的延迟,也不要优化。相反,应该进行性能分析。大部分应用程序的时间都会花费在一个“热”循环中,而这个循环通常并不直观。你需要真正的测量和科学来告诉你发生了什么。一旦你有了分析数据,你的优化任务应该从大到小进行:
  1. 架构优化。应用程序的整体结构是效率低下的根源吗?

  2. 算法优化:你是否使用了正确的数据结构?你是否以正确的方式访问它们?你的应用程序大部分时间是在写入还是读取?针对这个问题进行优化。

  3. 最后的选择。微调优化。简化热循环,或展开一些循环。Duff's Device。除非你确定其他两个级别无法再进一步改善,并且仍然没有达到性能目标,否则不要在这个级别上进行优化。这种优化可能会导致程序出现问题,使应用程序更难扩展,更脆弱,因此除非你真的必须这样做,否则不要这样做。

再次强调,不要浪费时间在优化任何看起来效率低下的代码上。优化需要投入大量时间和精力。在冒险之前,你应该有证据支持你的决定。

2
在正确操作之前考虑性能和优化是有区别的。前者不仅可以,而且是一个好主意;后者则存在争议。构建本质上性能较差的代码是愚蠢的。 - DocMax
当你完成全面的性能分析时,对于架构优化来说已经太晚了,而一些算法优化也会变得比较麻烦。 - David Thornley
@David - 你写的程序只有一小部分需要优化。不优化其他程序所节省的时间远远超过偶尔进行大修的时间,以我的经验来看。另一方面,我通常认为在SO上的人不会犯明显的错误...但我可能错了。 :) - Sarah Mei

1
你应该在构建应用程序后,并且只有在有证据表明瓶颈存在时(例如通过分析),才进行性能优化。也许您会发现,优化并不是必要的,尤其是因为编译器通常比您更擅长此项工作。

只有在性能不是要求,或者它是一个非常小而琐碎的程序时,你才应该等到完成。在大多数其他情况下,这样做为时已晚,更难以改变。 - Robert Paulson

0
什么时候需要考虑性能,什么时候不需要呢?
只要你有空余的时间思考正确性,就可以考虑性能了 :-)
大多数情况下,你会想:“这一部分的性能并不重要:因为整个应用程序的性能即使有这一部分也还是可以接受的,或者因为这一部分的成本与其他部分相比微不足道。”

这就是为什么许多程序只能勉强达到可接受的水平。如果我在我的最先进的四核系统上点击我的Open Office快捷方式,15K磁盘,它能够立即打开,那该有多好啊。 - Lawrence Dol
http://en.wikipedia.org/wiki/OpenOffice.org 上说:“批评者指出过多的代码膨胀和OpenOffice.org加载Java运行时环境可能是缓慢速度和过度内存使用的原因。” - ChrisW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接