我什么时候应该关心性能?


16

最长的时间是在Java的IRC通道,SO等位置上,有人告诉我“担心代码的外观及其现在的可读性/可理解性,以及在绝对必要时稍后再执行性能”。因此,在最长的时间里,我并没有真正针对小型台式机或Web应用程序的性能进行OCD,只是消除了效率低下的问题。

大多数回答是“可伸缩性如何?”。没错,但是如果我的应用程序仅能解析10,000行,那我应该为一小部分将要推送到1,000,000行文件中的人弄乱我的代码吗?

我的主要问题是,我何时应该以简单但效率低下的方式来处理大型复杂的大型野兽,这些野兽的处理速度极快,但却破坏了所有可能的升级方式,并使代码过于困难,并且容易被下一个开发人员重写。

Answers:


23

担心性能成为问题时。

如果您编写一个小型应用程序来处理10,000个行文件,而每100个文件中得到一个1,000,000个行文件,则处理该文件所花费的时间可能并不重要。但是,如果您经常要获取比初始文件大5到10倍的文件,而您的应用程序花费的时间太长而无法完成其工作,则可以开始进行性能分析和优化。

现在,我说“工作太久了”。由用户或赞助组织决定。如果我正在执行一项任务,并且花了5分钟才能完成某项工作,而我却花了3分钟时间却没有使用该软件或使用其他工具,则我可能会提交错误报告或维护请求以进行改进。

如果您是用户,则您的软件需要花多长时间来完成工作-只有您可以决定是否希望它做得更快,或者是否愿意等待更长的时间才能拥有更具可读性的代码。



我开始进行性能分析并进行优化如果1)工作耗时2)硬件资源之一达到最大值(例如100%cpu)
答:Binzxxxxxx

10

我的主要问题是,我何时应该以简单但效率低下的方式来处理大型复杂的大型野兽,这些野兽的处理速度极快,但却破坏了所有可能的升级方式,并使代码过于困难,并且容易被下一个开发人员重写。

这通常是错误的二分法。您可以编写出色的高效,可读性和可维护性的代码。您可以编写出效率低下,难以维护的混乱堆。

在处理性能问题时,我通常会尝试考虑要解决的业务问题。当客户使用软件时,我的软件将如何运行。我的应用程序性能会让Jacob Nielsen满意吗?


5
++假二分法!他们永远不会学习吗?当发现并解决性能问题时,代码不仅更快,而且更好。我仅感到遗憾的是,我只能提出一个支持!
Mike Dunlavey 2010年

+1表示这通常是错误的二分法……并非总是如此,但通常如此。
丹·罗森斯塔克

1
-1通常是错误的二分法-实际上,它通常是正确的,并且在极少数情况下,错误的二分法也是如此。在我从事编程工作的30多年中,我看到了太多的“精心设计”的性能优化,实际上使代码更难于理解和维护(并且经常进行优化,而某些事情根本不需要进行优化)。
布朗

5

我在大学期间学习微处理器的一种不言而喻的做法是:“快速处理常见问题。纠正不常见的问题。”

只要您只有一小部分用户使用输入要比其处理的输入量大两个数量级的代码来阻塞您的代码,请不要费力。如果他们给输入足够长的时间,请确保它能够正确处理输入,并且如果他们在完成工作之前将其杀死,也不会留下任何损坏成无用的东西。

但是,越来越多的人开始以这种方式使用它(或开始告诉您“我非常希望使用您在每周TPS报告中编写的工具,但这花了整整一天的时间”),您开始考虑为了维护性能而牺牲易维护性。


1

我的主要问题是,我何时应该以简单但效率低下的方式来处理大型复杂的大型野兽,这些野兽的处理速度极快,但却破坏了所有可能的升级方式,并使代码过于困难,并且容易被下一个开发人员重写。

“担心代码的外观及其现在的可读性/可理解性,以及如果绝对必要的话,稍后再提高性能”是一种简单的方法,通常无济于事。好的设计将易于维护,易于阅读且高效。

性能是良好设计的常见组成部分。如果您的程序缓慢且浪费,那么它实际上是不可重用的。当您需要解决该问题时,您会在客户端上强制进行更新,除非需要时间让他们进行更新。缓慢的程序会变得很麻烦,无法改善。然后他们选择一个替代方案,因为它不符合他们的需求。诊断,更新和处理对不良设计的改进所带来的副作用通常会超过编写它的最初开发时间,以使其高效,正确地工作并且总体上具有良好的设计。该程序具有很高的可重用性,并且维护成本低(获胜)。

因此,对您问题的简短回答是“不要浪费。编写可重用。在原型/开发概念证明时不要偷懒,但不要将原型用于生产代码。”

在编写生产程序和打算重用的程序时,请注意并避免浪费设计。在实现过程中,是编写程序的理想时机,不要浪费时间-您对细节及其操作有清晰的了解,并且在编写之后进行修复确实很痛苦且效率低下。很多人认为最后可能会进行一些分析(或者可能是一个问题),而重新设计/更改通常太耗时,并且效率低下而且如此之广泛,以至于您不了解该程序根据配置文件的结果很好。这种方法在实施过程中花费的时间很少,并且(假设您已经完成了足够多次)通常会使设计速度提高几倍,并且可以在更多环境中重用。不浪费 选择好的算法,考虑您的实现并重用正确的实现都是好的设计的全部内容;所有这些改善可读性,可维护性和重用性比伤害更多。


0

我试图使代码可读-性能太糟糕了。

当代码被证明过于缓慢时,我将其重构为更快。通常,重构过程中会伴随大量注释,因为代码的可读性往往较低。


0

嗯-从来没有?

认真地讲,应该始终编写代码以便于易于理解和维护。

至于何时处理性能问题,请在识别出问题后立即进行处理,而不要预先优化代码,因为那样您就只能猜测性能问题在哪里。

如果您编写的代码清晰,简洁,易于理解和可维护,则您或其他程序员应该毫无疑问地重构代码以使其更加高效。


3
我不同意这一点。性能要求是系统的有效非功能性要求。
汤玛斯·欧文斯

从技术上讲,如果明确定义了与性能相关的要求,则可以说您已经确定了性能问题,并且必须在解决方案中予以考虑。我要说的是提前变得聪明,这样您就可以避免非特定的“潜在”问题。
Noah Goodrich'9

啊。是的,在这种情况下,您绝对正确。您不必担心可能性,因为存在的可能性太多,而要专注于您所知道的。
托马斯·欧文斯

0

我通常首先编写要可读的代码。当且仅当我发现该程序运行太慢而无法完成其工作时,我才进行分析和优化。就是说,养成执行不影响代码可读性的常见优化的习惯并没有错。也就是说,如果一段代码可以用两种相等(或几乎相等)的可读方式编写,请选择通常更快的一种。

例如,在Python中,列表推导(或生成器表达式)往往比等效for循环快,因此如果不影响可读性,我将在可能的地方使用列表推导(例如,如果不影响列表推导,则不嵌套列表推导)我可以避免使用它,而是使用for循环,因为嵌套列表推导可能很难从心理上进行解析。

同样,不可变数据类型往往比可变数据类型快,因此我会尽可能使用不可变数据类型。


0

如果您在真正对性能至关重要的领域中工作,那么您就不能不考虑效率问题。在这些情况下及早进行设计,并以与最终结果的可维护性相关的方式进行设计,这是最关键的事情之一。

您不能设计和实现大型服务器,而只是开始编写简单,文档完善的代码,而该代码仅对全局函数使用阻塞函数,而全局线程锁则锁定整个系统以处理每个单独的客户请求,而不会放置任何请求认为任何东西进入共享状态,线程争用和异步性。这是灾难的秘诀,并且需要重新设计和重写您编写的大量精美文档的代码,这些代码可能会导致可以想象的最难维护的代码库,而由于尝试而导致竞争状况和死锁事后才可以达到所需的效率,而不是仅仅预先考虑有效,简单,可行的设计。

一个游戏开发团队投入了8个月的生产时间,其引擎在其最强大的32核硬件上仅以每秒2帧的速度运行,而每次屏幕忙碌时往往会停顿15秒钟,这不太可能立即获得可用的产品修复一个局部的热点。很有可能他们的设计是FUBAR,在某种程度上可以重新审视绘图板和设计变更,这些变更可以层叠到代码库的每个角落。

他曾与John Carmack讨论过如何将技术演示以每秒至少数百至数千帧的速度运行以将其集成到生产中。这并不是对效率的不健康追求。他预先知道游戏需要整体以30 FPS以上的速度运行,以使客户满意。结果,像软阴影系统这样的小方面不能以30 FPS的速度运行,否则整个游戏可能无法足够快地提供所需的实时反馈。在达到所需的效率之前,它是无法使用的。在对效率有根本要求的此类关键性能领域中,一种解决方案无法达到足够的速度实际上并不比根本不起作用的解决方案好,。而且,除非您事先就其效率进行了大量的思考,否则您将无法设计出一种高效的软阴影系统,该系统无法按实时游戏引擎的要求每秒运行数百至数千帧。实际上,在这种情况下,90%以上的工作都围绕效率而进行,因为提出一个软阴影系统很简单,该系统使用路径跟踪在每帧2小时的工作时间就可以正常工作,但是您不能指望对其进行调整以每秒数百帧的速度运行,而方法却没有完全不同的变化。

当效率是应用程序设计的基本部分时,您不能期望在事后了解中实现效率,而不会浪费比忽略它节省的时间更多的时间,因为您不能期望在事后了解中实现可行的设计。没有人说:“ 可以推迟到以后再考虑设计。只要很好地编写代码,以后您就可以提出适当的设计。” 但是,在对性能至关重要的体系结构中,如果您不对高效的设计进行过多的关注和思考,那么这就是您有效的工作。

现在,这并不意味着您必须立即对实现进行微调。有关实现的详细信息,如果不需要更改设计,在进行测量后,仍有很大的空间可以迭代到更快的解决方案,并且通常这是最有效的解决方案。但是在设计级别,这确实意味着您必须从一开始就充分考虑设计和体系结构与效率之间的关系。

这里的关键区别是设计。在事后看来,对设计进行大的更改并不容易,因为设计会累积依赖关系,如果设计发生更改,依赖关系就会中断。而且,如果某个设计要求具有合理的效率,或者在某些情况下,其质量在很大程度上取决于其效率,那么您不应该期望事后才能够实现正确的设计。对于效率是质量至关重要的竞争产品,无论是操作系统,编译器,视频处理器,光线跟踪器,游戏引擎还是物理引擎,从一开始就认真考虑了效率和数据表示的思想。在那种情况下,将太多的思想放在效率的前面并不是过早的优化。正是在最有生产力的时候将这样的想法付诸实践

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.