优化真正值得花费时间的时候是什么时候?

10

在我上一个问题后,我想了解何时进行优化真正值得开发人员花时间。

为了让查询快20%,值得花费4小时吗?是、否、可能、只有当……?

“浪费”7个小时将一个任务切换到另一种语言以节省约40%的CPU使用率“值得吗”?

我的新项目的正常迭代流程是:

  1. 理解客户的需求及意图;
  2. 规划项目:使用哪些语言以及在何处,数据库设计;
  3. 开发项目;
  4. 测试和修复错误;
  5. 对运行项目进行最终分析和最终优化;
  6. 如果需要,进一步分析资源的实际使用情况并进行进一步优化;

“编写良好且易于维护的代码”是暗示。

很明显,“优化”的重头戏发生在第2点,但通常在项目结束后审核代码时,我会发现一些部分即使它们工作得很好,也可以改进。这就是第5点的理由。

为了给出最后一点的具体例子,一个简单的例子是当我预计90%的查询为SELECT而10%为INSERT/UPDATE时,因此我在数据库表上创建了索引。但是,6个月后,我发现实际情况是有10%的SELECT查询和90%的INSERT/UPDATE,因此查询速度没有优化。这是我想到的第一个例子(显然这更像是对最初错误设计的“修补”而不是优化;)。

请注意,我是一名开发人员,而不是商人,但我喜欢尽可能地给我的客户提供最好的服务以保持良心。

我的意思是,如果我花费50小时来获得应用程序总速度提升的5%,而该应用程序由10个用户使用,那么这可能不值得时间......但是什么情况下值得呢?

你认为何时进行优化至关重要?

你通常应用什么公式,知道优化所花费的时间(和最终收益)并不总是可以在纸上量化的?

编辑:抱歉,但我不能接受诸如“除非人们对 id 进行抱怨,否则不需要进行优化”之类的答案;这可能是一种商业观点(有争议,依我看),但不是一个开发者或者(依我看)一个好的回答。我知道,这个问题非常主观。

我同意Cheeso的看法,应该在分析项目的实际使用和负载后推迟性能优化,但在项目结束后可以立即进行小型且快速的优化。

感谢大家;)


1
+1 - 这是一个有趣的问题。我已经为您修正了语法。 - ire_and_curses
9个回答

7

YAGNI,除非有很多人抱怨。


编辑:我构建了一个比其他替代品稍慢的库。它仍然获得了使用和份额,因为它更易于使用且更强大。我继续投资于功能和能力,推迟对性能的任何工作。

在某个时刻,有足够的功能,性能浮出水面成为首要任务,我最终花了一些时间改进性能,但只是在长时间考虑工作量之后。

我认为这是正确的方法。


有点同意,但你无法从一开始就知道你的网站会有多少访问者,或者项目在未来3年内将处理多少数据 ;) - Strae
2
在2.5年内担心3年后的事情,今天担心你无法知道的事情是浪费金钱。 - user177800
3
我明白了,所以你的意思是在收到漏洞报告之前就假定你的产品是高品质的。这真是敏捷的做法。 - Aaronaught
2
假设人们会实际提出投诉而不是只是不使用你的产品是有问题的。一个典型的用户可能无法感知问题与性能有关,但仍会因此感到沮丧。这并不一定是确定是否需要改进性能的最佳指标。 - Bryan M.
2
你的观点很有道理。但总体而言,我认为性能应该被推迟。 - Cheeso

6

这里至少有两个需要提到的“效率”类别:

  • UI应用程序(及其依赖项),其中最重要的衡量标准是响应用户的时间

  • 批处理,其中主要指标是总运行时间


在第一种情况下,有关于响应时间的规则。如果您关心产品质量,需要保持响应时间短。当然,响应时间越短越好,但是以下是关键点:
  • 对于“立即”响应,100毫秒内需要发生动画和其他“实时”活动;

  • 对于“不间断”响应,1秒钟内需要完成。超过这个时间,用户会感到沮丧;此时您还需要考虑显示进度屏幕。

  • 对于保留用户焦点,10秒钟是极限。超过这个时间,您的用户会非常生气。

如果您发现有多个操作需要超过10秒,并且您可以通过合理的努力解决性能问题(我认为没有硬性限制,但个人认为绝对少于1个月的工作量,可能少于3-4个月的工作量),那么您应该一定要付出努力来解决它。

同样的,如果你发现应用程序的加载时间超过了1秒,那么你应该尽力使其更快。至少,比较一下改进应用程序性能所需的时间和重新设计每个缓慢屏幕并添加进度对话框和后台线程(用户可以取消)所需的时间 - 因为如果应用程序太慢,这是你作为设计师的责任。
但不要仅基于此做出决定 - 用户体验也很重要。如果加入异步进度对话框需要1周时间,而将运行时间缩短到1秒以下需要3周时间,我仍然会选择后者。在我看来,如果问题是应用程序范围内的,则在一个人月以内的任何时间都是合理的;如果只是一个相对不经常运行的报告,我可能会放弃它。
如果你的应用程序是实时的,比如与图形有关,那么我会把它归类为非实时应用程序的10秒标记。也就是说,你需要尽一切可能加速它。在游戏或图像编辑器中闪烁是不可接受的。在音频处理中,卡顿和故障也是不可接受的。即使对于像文本输入这样基本的功能,按键被按下和字符出现之间的500毫秒延迟是完全不可接受的,除非你通过远程桌面等方式连接。为解决这些问题付出的努力永远不会太多。
现在让我们来看看第二种情况,我认为这大部分是不言自明的。如果你正在进行批处理,则通常存在可扩展性问题。只要批处理能够在规定的时间内运行,你就不需要改进它。但是,如果你的数据正在增长,如果批处理应该在一夜之间运行,并且你开始看到它在清晨时分逐渐变得缓慢,并打断了人们在上午9:15的工作,那么显然你需要解决性能问题。
实际上,你真的不能等那么久;一旦它无法按照所需时间完成,你可能已经遇到了大麻烦。你必须积极监控情况并保持一定的安全余量 - 比如说在可用的6小时中最多运行5个小时,然后你就开始担心了。
因此,批处理的答案是显而易见的。你有一个硬性要求,即该批处理必须在一定时间内完成。因此,如果你接近边缘,性能必须得到改善,无论它有多难/昂贵。问题接下来就是 什么是最经济有效的提高流程的方式?

如果仅仅投入更多的硬件就能显著降低成本(而且你确信问题确实与硬件相关),那么不要花时间优化,只需购买新的硬件。否则,找出设计优化和硬件升级的最佳组合,以获得最好的投资回报率。在这一点上,几乎纯粹是一个成本决策。


这就是我对这个主题的全部看法。回应“YAGNI”观点的人应该感到羞耻。你的职业责任是了解或至少查明是否“需要它”。假设任何事情都可以接受直到客户抱怨是对这种责任的放弃。
仅仅因为你的客户不要求它,并不意味着你不需要考虑它。你的客户也不要求单元测试,甚至没有合理的/可维护的代码,但你仍然提供这些东西,因为这是你的职业的一部分。最终,你的客户会更喜欢一个流畅、快速的产品,而不是其他开发者中心化的东西。

1
优化工作越长,产生的回报可能会递减,因此需要在平衡中做出取舍。但是很多程序员甚至不尝试优化明显太慢的东西,这让我感到沮丧,因为通常只需花费极少的努力就可以获得巨大的性能提升。 - Steve Wortham

5
优化只有在必要时才值得进行。
如果我们已经向客户承诺,假日套餐搜索的响应时间在5秒以内,并且系统将在单个Oracle服务器上运行(无论规格如何),而在高峰负载时搜索需要30秒,那么优化绝对是值得的,因为否则我们将无法获得报酬。
当您最初开发系统时,如果您是一位好的开发人员,您会设计高效的系统,而不会浪费时间进行过早的优化。如果最终的系统速度不够快,您就需要进行优化。但是您的问题似乎暗示着您可能会进行某些模糊的额外优化,如果您觉得值得这样做的话。这不是一个好的思考方式,因为它意味着您没有明确的目标。您需要与利益相关者讨论并设定一些目标,然后再开始担心需要进行什么样的优化。

++ 这是很好的常识(其他答案也有)。就个人而言,我与大多数人分道扬镳的地方在于性能成为问题并且需要采取措施的步骤。这就是我依靠鲜为人知的堆栈快照魔法技术(https://dev59.com/qnRC5IYBdhLWcg3wG9Rb#1562802)来找出发生了什么以及需要修复什么的地方。 - Mike Dunlavey

1

就像其他问题的答案中每个人所说的那样,当更改某些内容具有经济意义时,则需要进行更改。在大多数情况下,“足够好”就能赢得胜利。如果客户没有抱怨,则已经足够好了。如果他们正在抱怨,则修复它,直到他们停止抱怨。敏捷方法将为您提供一些关于如何知道何时足以的指导。如果某些东西使用的 CPU 比您认为需要多 40%,但它仍能正常工作且客户感到满意,则已经足够好了。真的很简单,让它正常工作和可维护,然后等待可能永远不会出现的投诉。

如果您担心的问题真的是个问题,那么任何人都永远不会开始使用 Java 来构建关键任务的服务器端应用程序。或者 Python 或 Erlang 或其他不是 C 的语言。而且,如果他们这样做了,即使是获取第一个您担心失去的客户的时间框架也无法完成任务。在它成为问题之前很久您就会知道需要做出改变。


1

大家好,发帖很棒。

你们有没有注意到在简单的SELECT中不必要地使用事务吗?我曾经在这方面吃过亏...我还进行了一些代码清理,发现有很多图表返回,可能只需要10条记录....等等...有时候问题不在于你自己的代码,而是别人偷懒省事...祝好运!


0
如果客户认为没有必要进行性能优化,那么就没有理由去执行。
在项目开始时,与客户定义可衡量的性能需求SLA(例如,在2秒内完成95%的查询),这让你知道是否达到了目标或者是否需要更多的优化。在当前和预估未来负载下的性能测试可以提供你需要的数据,以确定是否满足SLA要求。

0

在你知道需要优化什么之前,优化很少有意义。请记住,如果I/O基本上处于空闲状态且CPU较低,则计算机无法发挥其作用。显然,您不希望CPU一直处于高负载状态,也不希望I/O带宽不足,但请意识到,试图让计算机在执行强烈操作的同时基本上整天处于空闲状态是不现实的。

等到达到预定阈值(我通常使用80%利用率作为标准,其他人认为这太高/太低),然后在必要时进行优化。请记住,最好的解决方案可能是扩展或缩小规模,而不是实际优化软件。


0

当你在优化上花费很少的时间就能获得良好的加速效果时,优化是值得投入时间的。为了达到这个目的,你需要工具/技术,可以让你非常快速地找到最有益于优化的代码。

通常人们认为找到那段代码的方法是通过测量函数所花费的时间,但我认为这只提供了一些线索 - 你仍然需要像侦探一样去寻找。带我直接到代码的是stackshots以下是一个例子,通过查找和修复几个问题,实现了40倍的加速效果。其他人在SO上报告了从7到60的加速因子,而且只需付出很少的努力即可实现。

*(7x: 评论1。60x: 评论30。)


0

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