"Premature Optimization": A discussion

Started by
37 comments, last by neurokaotix 20 years, 5 months ago
"premature optimization is the root of all evil." Do you agree? I for one do not agree that all premature optimization is necessarily bad. I also think that there is a difference between premature optimization and using methods which aren''t a blatant waste of cycles. I''ll quote a recent article on this site:
quote:Finally, a word about performance. While these idioms can help you write safer and more robust programs, there is a cost associated with them, both in code size and performance overhead. You may not be checking the bounds of std::vector or std::string, but the code inside them certainly is, and this costs CPU cycles. So, you might conclude that the moral of the story is that while this stuff is nice in theory, your application needs to scream, so in reality you''ll just continue using good old fashion pointers, arrays, and homegrown containers. Right? Wrong. As a wise programmer once said, premature optimization is the root of all evil. Do things the safe way first. If your program is slower than you need, *profile it* in a profiler and find the bottlenecks. Then and only then hand tune the offending code. Chances are -- especially in graphics applications and games -- the bottlenecks in your code won''t be in the C++ standard library, but rather in your algorithms.
If you want to use char instead of std::string because you don''t need the extra luggage then I don''t consider that "premature optimization" at all. Any thoughts on the topic? James Simmons MindEngine Development http://medev.sourceforge.net
Advertisement
It all depends. Which is why premature optimization is the root of all evil: You often create problems that didn''t exist in the first place.

If you''re doing something where the overhead of std::string could possibly matter, you''d better be doing some seriously wicked data processing, and certainly not games. What kind of game plays with text in really tight loops?
char <-> std::string was just an example, another might be std:list and your own list which you''ve specialized for your own purposes.

James Simmons
MindEngine Development
http://medev.sourceforge.net
GOOD: Choice of appropriate algorithms, data structures, architechture etc at ANALYSIS and DESIGN time.

I wouldn''t call that optimisation but it plays a big part in the final performance of your software. Of course experience learnt from the profiling and optimisation of previous products helps intuition about which algorithms and data structures may be more suitable. [BTW: I definately don''t include micro optimisations in this]

BAD: Not planning/designing, making assumptions without a clear/complete picture of the overall system and making micro optimisations in the middle of coding (usually based on false assumptions about what the compiler will do).

IMO: all actual optimisation (as opposed to optimal design) should be profiler led and only performed after a module or the whole system is working and tested. Anything else is making assumptions and is stabbing in the dark - if you don''t profile, you end up wasting time optimising things which don''t matter and ignore the ones that do!

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Get a profiler before you optimize, get a free one here: http://www.compuware.com/products/devpartner/profiler/default.asp.

[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
I would say that premature micro-optimzations which decrease readability and maintainability are the root of all evil.

Well, okay, just some evil.

The main point to glean from a discussion of premature optimization is that there''s more to code than its tested execution speed. Code must be able to be understood and modified further down the road; it must in some cases be proven to be robust; it may need to be instrumented for unit testing; it may need to be ported to a system with different capabilities. When writing your code, you need to make design decisions such as what to optimize and how based on the impact of the decision on the entire development process. Far too many programmers get tunnel vision at this point, seeing only the execution trace, and hobble their code with optimizations.

neurokaotix, you say that one often shouldn''t use std::string because of the "extra luggage". Yet do you know what, exactly, that luggage is? do you know what its effect on runtime performance is? Do you know how a char-array would accomplish needed functionality without replicating that luggage in some other way? Many people wrongly assume that library containers such as std::string are a priori inefficient, simply because they are convenient. That equation--convenience and inefficiency--is a dated and dangerous holdover from the early days of high-level programming languages which needs to be nipped in the bud from the minds of neophyte programmers before it takes root. One of the major design concepts of modern languages such as C++ is to give programmers convenience _without_ sacrificing efficiency. A healthy understanding of how C++ does this, as well as knowledge of how to work within that framework by doing things like defining custom allocators instead of tossing it out the window and going back to calloc() and char*''s, is a very useful thing, much more useful than never using STL in time-critical code.

How appropriate. You fight like a cow.
I agree that premature optimization is not a good idea when you have the time to develop. As long as you know what interface a class will have, you can easily implement a wrapper that really uses STL or the like and then later change the code to be faster while leaving the interface to be the same.
For example, I think memory management will be one bottleneck in my scripting language, so I did some research. I found that it in memory intensive applications, it can be a problem, and I found many solutions to the problem. I also found a very interesting thesis somebody did on it, and I really like the interface they used, so I copied their basic interface to the memory manager and for now just filled in the functions to use malloc and free. If, in the future, memory management becomes a speed problem, I''ll replace the calls to malloc and free inside the memory manager class with whatever complex algorithm seems appropriate. I even have a template function for allocating classes, so I can specialize it and have different classes get allocated in different ways if that seems efficient.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
I''m simply making a blind assumption that std::string has extra luggage that slows things down. :/

James Simmons
MindEngine Development
http://medev.sourceforge.net
quote:Original post by neurokaotix
"premature optimization is the root of all evil."

Do you agree? I for one do not agree that all premature optimization is necessarily bad. I also think that there is a difference between premature optimization and using methods which aren't a blatant waste of cycles.


Premature, n: happening, arriving, existing, or performed before the proper, usual, or intended time.

Hence, premature optimization is always bad. The key is to know when the proper time is. And also to know what is a 'blatant waste of cycles' and what is inevitable overhead. Choosing the proper algorithms and data structures for a given problem is not premature optimization, it is design . And doing it right *is* difficult and takes more knowledge than 'noobs' think.

In the end, picking an O(n log n) algorithm over an O(n^3) will probably bring better results than writing your own dynamic array class.

Remember that the best optimization you can apply to a program is the one that takes it from a non-working state to a working state. There is no point to engaging into bit twiddling until you actually have a program that runs and can be profiled. How many projects here die because the programmers spend there time reinventing strings or linked lists "for performance" instead of working on getting the game done ?

quote:If you want to use char instead of std::string because you don't need the extra luggage then I don't consider that "premature optimization" at all.


Does that mean you should use char*, with all their clunkiness all over your programs ? Don't you think it would be much smarter to use std::string in your program, and to strip it down to char* in the narrow spots where it is really necessary ? If you do it properly, the code calling your function should never notice the difference.

Especially on these boards, 'optimization' is often used to justify superstition; sloppy programming; ignorance of language features, idioms and libraries; and the infamous Not-Invented-Here Syndrome.

-- edit --
quote:char <-> std::string was just an example, another might be std:list and your own list which you've specialized for your own purposes.


Which implies you had your list already written before your project started (code reuse). Otherwise that is premature optimization.

quote:I'm simply making a blind assumption that std::string has extra luggage that slows things down. :/


My point, exactly. People make assumptions or rely on hearsay instead of actually learning how things work. Not attacking you personally, but, I wouldn't trust somebody making these assumptions with the job of efficiently reimplementing standard library components, nor to do it with a decent interface (STL-compatible == good)

[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

[edited by - Fruny on November 5, 2003 5:35:32 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
quote:Original post by neurokaotix
I''m simply making a blind assumption that std::string has extra luggage that slows things down. :/

Bad neurokaotix! No cha shu buns for you!

...aw, I just can''t stay mad at you. Here, have a cha shu bun.

How appropriate. You fight like a cow.

This topic is closed to new replies.

Advertisement