什么时候优化为时过早?
我看到这个词用得很多,但我觉得大多数人使用它是出于懒惰或无知。例如,我正在阅读这篇文章:
http:// blogs.msdn.com/b/ricom/archive/2006/09/07/745085.aspx
,他在其中谈论了他为实现应用程序所需类型而做出的决定。
如果是我,在我们需要编写的代码中谈论这些,其他程序员可能会这样想:
- 我在什么都没有的情况下考虑太多,从而过早地优化。
- 当没有遇到速度减慢或性能问题时,过度考虑无关紧要的细节。
或两者兼而有之。
并建议只实施它,不要担心这些,直到它们成为问题。
哪个更优惠?
在完成任何实施之前,如何区分性能关键型应用程序的过早优化与明智决策?
I see this term used a lot but I feel like most people use it out of laziness or ignorance. For instance, I was reading this article:
http://blogs.msdn.com/b/ricom/archive/2006/09/07/745085.aspx
where he talks about his decisions he makes to implement the types necessary for his app.
If it was me, talking about these for code that we need to write, other programmers would think either:
- I am thinking way too much ahead when there is nothing and thus prematurely optimizing.
- Over-thinking insignificant details when there is no slowdowns or performance problems experienced.
or both.
and would suggest to just implement it and not worry about these until they become a problem.
Which is more preferential?
How to make the differentiation between premature optimization vs informed decision making for a performance critical application before any implementation is done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
如果出现以下情况,优化就为时过早:
您的应用程序没有执行任何对时间要求严格的操作。 (这意味着,如果您正在编写一个将文件中的 500 个数字相加的程序,那么“优化”这个词根本不应该出现在您的大脑中,因为它只会浪费您的时间。)
您正在做一些除汇编之外的时间紧迫的事情,并且仍然担心
i++; 是否有效。 i++;
更快,或者i += 2
...如果它真的那么重要,那么您将在汇编中工作,而不是浪费时间担心这个。 (即使如此,这个特定的示例很可能并不重要。)您有一种预感,一件事可能比另一件事快一点,但您需要查找它。例如,如果您对
StopWatch
更快还是Environment.TickCount
哪个问题感到困扰,那么这是过早的优化,因为如果差异更大,您可能会更确定并且不需要查找它。如果您猜测某些事情可能会很慢但又不太确定,只需添加
//NOTE: Performance?
注释,如果稍后遇到瓶颈,请检查代码中的此类位置。我个人并不担心不太明显的优化;如果需要的话,我稍后会使用分析器。另一种技术:
我只是运行我的程序,用调试器随机中断它,然后查看它在哪里停止 - 它停止的地方可能是瓶颈,并且在那里停止的次数越多,瓶颈就越严重。它的作用几乎就像魔术一样。 :)
Optimization is premature if:
Your application isn't doing anything time-critical. (Which means, if you're writing a program that adds up 500 numbers in a file, the word "optimization" shouldn't even pop into your brain, since all it'll do is waste your time.)
You're doing something time-critical in something other than assembly, and still worrying whether
i++; i++;
is faster ori += 2
... if it's really that critical, you'd be working in assembly and not wasting time worrying about this. (Even then, this particular example most likely won't matter.)You have a hunch that one thing might be a bit faster than the other, but you need to look it up. For example, if something is bugging you about whether
StopWatch
is faster orEnvironment.TickCount
, it's premature optimization, since if the difference was bigger, you'd probably be more sure and wouldn't need to look it up.If you have a guess that something might be slow but you're not too sure, just put a
//NOTE: Performance?
comment, and if you later run into bottlenecks, check such places in your code. I personally don't worry about optimizations that aren't too obvious; I just use a profiler later, if I need to.Another technique:
I just run my program, randomly break into it with the debugger, and see where it stopped -- wherever it stops is likely a bottleneck, and the more often it stops there, the worse the bottleneck. It works almost like magic. :)
(我相信)这句谚语并不是指在创建良好设计时内置的优化。它指的是专门针对绩效的任务,否则这些任务将不会被执行。
根据常识,这种优化不会“变得”不成熟——在被证明无罪之前,它是有罪的。
This proverb does not (I believe) refer to optimizations that are built into a good design as it is created. It refers to tasks specifically targeted at performance, which otherwise would not be undertaken.
This kind of optimization does not "become" premature, according to the common wisdom — it is guilty until proven innocent.
过早优化是指在您知道有必要进行这种权衡之前,以牺牲代码的其他一些积极属性(例如可读性)为代价来进行性能优化。
通常,过早的优化是在开发过程中进行的,没有使用任何分析工具来查找代码中的瓶颈。在许多情况下,优化会使代码更难维护,有时还会增加开发时间,从而增加软件成本。更糟糕的是……一些过早的优化根本不会使代码变得更快,在某些情况下甚至可能使代码比以前慢。
Premature optimization is making an optimization for performance at the cost of some other positive attribute of your code (e.g. readability) before you know that it is necessary to make this tradeoff.
Usually premature optimizations are made during the development process without using any profiling tools to find bottlenecks in the code. In many cases the optimization will make the code harder to maintain and sometimes also increases the development time, and therefore the cost of the software. Worse... some premature optimizations turn out not to be make the code any faster at all and in some cases can even make the code slower than it was before.
优化是使现有代码运行更高效(更快的速度和/或更少的资源使用)的过程,
如果程序员没有证明有必要,那么所有优化都是不成熟的。 (例如,通过运行代码来确定它是否在可接受的时间范围内实现了正确的结果。这可以像运行它来“查看”它是否运行得足够快一样简单,或者在探查器下运行以更仔细地分析它) 。
良好的编程有几个阶段:
1) 设计解决方案并选择一个好的、高效的算法。
2) 以可维护、编码良好的方式实施解决方案。
3) 测试该解决方案,看看它是否满足您对速度、RAM 使用情况等的要求(例如“当用户单击“保存”时,花费的时间是否少于 1 秒?”如果需要 0.3 秒,那么您确实不需要)不需要花一周的时间优化它才能将时间降低到0.2s)
4) 如果不满足要求,请考虑原因。在大多数情况下,这意味着您现在已经更好地理解了问题,请转到步骤 (1) 寻找更好的算法。 (编写快速原型通常是一种廉价探索的好方法)
5)如果它仍然不满足要求,开始考虑可能有助于加快运行时间的优化(例如,查找表、缓存等)。为了推动这一过程,分析通常是一个重要的工具,可以帮助您找到代码中的瓶颈和低效率,这样您就可以从花在代码上的时间获得最大的收益。
我应该指出,一个经验丰富的程序员处理一个相当熟悉的问题可能能够在精神上跳过第一步,然后只应用一种模式,而不是每次都亲自经历这个过程,但这只是一个捷径,通过经验获得
因此,有经验的程序员会自动将许多“优化”构建到他们的代码中。这些与其说是“过早的优化”,不如说是“常识性的效率模式”。这些模式快速且易于实现,但极大地提高了代码的效率,并且您不需要进行任何特殊的计时测试来确定它们是否有好处:
例如,我刚刚替换了我们项目中的一段旧代码。我的新代码没有以任何方式“优化”,但是(与原始实现不同)它是在编写时考虑到效率的。结果:我的运行速度快了 25 倍 - 仅仅是因为不浪费。我可以优化它以使其更快吗?是的,我可以轻松获得另外 2 倍的加速。我会优化我的代码以使其更快吗?不 - 速度提高 5 倍就足够了,我已经达到了 25 倍。此时进一步的工作只会浪费宝贵的编程时间。 (但如果需求发生变化,我可以在将来重新访问代码)
最后,最后一点:您正在工作的领域决定了您必须满足的标准。如果您正在为游戏编写图形引擎或为实时嵌入式控制器编写代码,您可能会发现自己做了很多优化。如果您正在编写像记事本这样的桌面应用程序,那么只要不过度浪费,您可能永远不需要优化任何内容。
Optimisation is the process of making existing code run more efficiently (faster speed, and/or less resource usage)
All optimisation is premature if the programmer has not proven that it is necessary. (For example, by running the code to determine if it achieves the correct results in an acceptable timeframe. This could be as simple as running it to "see" if it runs fast enough, or running under a profiler to analyze it more carefully).
There are several stages to programming something well:
1) Design the solution and pick a good, efficient algorithm.
2) Implement the solution in a maintainable, well coded manner.
3) Test the solution and see if it meets your requirements on speed, RAM usage, etc. (e.g. "When the user clicks "Save", does it take less than 1 second?" If it takes 0.3s, you really don't need to spend a week optimising it to get that time down to 0.2s)
4) IF it does not meet the requirements, consider why. In most cases this means go to step (1) to find a better algorithm now that you understand the problem better. (Writing a quick prototype is often a good way of exploring this cheaply)
5) IF it still does not meet the requirements, start considering optimisations that may help speed up the runtime (for example, look-up tables, caching, etc). To drive this process, profiling is usually an important tool to help you locate the bottle-necks and inefficiences in the code, so you can make the greatest gain for the time you spend on the code.
I should point out that an experienced programmer working on a reasonably familiar problem may be able to jump through the first steps mentally and then just apply a pattern, rather than physically going through this process every time, but this is simply a short cut that is gained through experience
Thus, there are many "optimisations" that experienced programmers will build into their code automatically. These are not "premature optimisations" so much as "common-sense efficiency patterns". These patterns are quick and easy to implement, but vastly improve the efficiency of the code, and you don't need to do any special timing tests to work out whether or not they will be of benefit:
For example, I just replaced an old piece of code in our project. My new code is not "optimised" in any way, but (unlike the original implementation) it was written with efficiency in mind. The result: Mine runs 25 times faster - simply by not being wasteful. Could I optimise it to make it faster? Yes, I could easily get another 2x speedup. Will I optimise my code to make it faster? No - a 5x speed improvement would have been sufficient, and I have already achieved 25x. Further work at this point would just be a waste of precious programming time. (But I can revisit the code in future if the requirements change)
Finally, one last point: The area you are working in dictates the bar you must meet. If you are writing a graphics engine for a game or code for a real-time embedded controller, you may well find yourself doing a lot of optimisation. If you are writing a desktop application like a notepad, you may never need to optimise anything as long as you aren't overly wasteful.
刚开始时,交付产品比优化更重要。
随着时间的推移,您将分析各种应用程序,并学习编码技能,这些技能自然会导致优化代码。基本上在某个时候你将能够发现潜在的问题点并相应地构建东西。
不过,在发现实际问题之前不要着急。
When starting out, just delivering a product is more important than optimizing.
Over time you are going to profile various applications and will learn coding skills that will naturally lead to optimized code. Basically at some point you'll be able to spot potential trouble spots and build things accordingly.
However don't sweat it until you've found an actual problem.
当您的编码经验不足 10 年时。
When you have less that 10 years of coding experience.
拥有(大量)经验可能是一个陷阱。我认识许多非常有经验的程序员(C\C++、汇编),他们往往担心太多,因为他们习惯于担心时钟滴答和多余的位。
在嵌入式或实时系统等领域,这些确实很重要,但在常规 OLTP/LOB 应用程序中,您的大部分精力应该集中在可维护性、可读性和可更改性上。
Having (lots of) experience might be a trap. I know many very experienced programmers (C\C++, assembly) who tend to worry too much because they are used to worry about clock ticks and superfluous bits.
There are areas such as embedded or realtime systems where these do count but in regular OLTP/LOB apps most of your effort should be directed towards maintainability, readability and changeabilty.
优化是很棘手的。考虑以下示例:
我的底线很简单。优化是一个广义的术语。当人们谈论过早优化时,他们并不意味着您需要只做想到的第一件事而不考虑整体情况。他们说你应该:
这实际上一切都取决于您的经验。如果您是图像处理方面的专家,并且有人要求您做一些您以前做过十次的事情,您可能会从一开始就推动所有已知的优化,但这没关系。过早优化是指当您尝试优化某项内容时,您一开始并不知道它需要优化。原因很简单——它有风险,浪费你的时间,而且更难维护。因此,除非您经验丰富并且以前曾走过这条路,否则在不知道存在问题的情况下不要进行优化。
Optimization is tricky. Consider the following examples:
My bottom line here is simple. Optimization is a broad term. When people talk about premature optimization, they don't mean you need to just do the first thing that comes to mind without considering the complete picture. They are saying you should:
It really all boils down to your experience. If you are an expert in image processing, and someone requests you do something you did ten times before, you will probably push all your known optimizations right from the beginning, but that would be ok. Premature optimization is when you're trying to optimize something when you don't know it needs optimization to begin with. The reason for that is simple - it's risky, it's wasting your time, and it will be less maintainable. So unless you're experienced and you've been down that road before, don't optimize if you don't know there's a problem.
请注意,优化不是免费的(就像啤酒一样)
所以在优化任何东西之前,你应该确保它是值得的。
您链接到的 Point3D 类型似乎是某些东西的基石,并且优化的情况可能是显而易见的。
就像 .NET 库的创建者在开始优化 System.String 之前不需要任何测量一样。但他们必须在此期间进行测量。
但大多数代码对最终产品的性能并没有发挥重要作用。这意味着优化方面的任何努力都被浪费了。
除此之外,大多数“过早的优化”都是未经测试/未经测量的黑客行为。
Note that optimization is not free (as in beer)
So before optimizing anything, you should be sure it's worth it.
That Point3D type you linked to seems like the cornerstone of something, and the case for optimization was probably obvious.
Just like the creators of the .NET library didn't need any measurements before they started optimizing System.String. They would have to measure during though.
But most code does not play a significant role in the performance of the end product. And that means any effort in optimization is wasted.
Besides all that, most 'premature optimizations' are untested/unmeasured hacks.
如果您在实施的早期阶段花费太多时间来设计优化,那么优化就为时过早。在早期阶段,您有更好的事情需要担心:实现核心代码、编写单元测试、系统相互通信、UI 以及其他任何事情。优化是有代价的,您很可能会浪费时间来优化不需要的东西,同时创建更难维护的代码。
仅当您的项目有具体的性能要求时,优化才有意义,并且在初始开发之后,性能将很重要,并且您已经实施了足够的系统,以便实际测量您需要测量的任何内容。切勿在没有测量的情况下进行优化。
随着您获得更多经验,您可以在进行早期设计和实现时着眼于未来的优化,也就是说,尝试以这样的方式进行设计,以便更容易衡量性能并在以后进行优化(如果有必要的话) 。但即使在这种情况下,您也不应该在开发的早期阶段花很少的时间进行优化。
Optimizations are premature if you spend too much time designing those during the earlier phases of implementation. During the early stages, you have better things to worry about: getting core code implemented, unit tests written, systems talking to each other, UI, and whatever else. Optimizing comes with a price, and you might well be wasting time on optimizing something that doesn't need to be, all the while creating code that is harder to maintain.
Optimizations only make sense when you have concrete performance requirements for your project, and then performance will matter after the initial development and you have enough of your system implemented in order to actually measure whatever it is you need to measure. Never optimize without measuring.
As you gain more experience, you can make your early designs and implementations with a small eye towards future optimizations, that is, try to design in such a way that will make it easier to measure performance and optimize later on, should that even be necessary. But even in this case, you should spend little time on optimizations in the early phases of development.