General C++ Performance Improvement Tips [closed]
Could someone point me to an article, or write some tips right here about some C++ programming habits that are generally valid (no real drawbacks) and improves performance? I do not mean programming patterns and algorithm complexity - I need small things like how you define your functions, things to do/to avoid in loops, what to allocate on the stack, what on the heap, and so on.
It's not about making a particular software faster, also it's not about how to create a clean software design, but rather programming habits that - if you always apply them, you will make your code rather a little bit faster than a little bit slower.
A number of the tips in Effective C++, More Effective C++, Effective STL and C++ Coding Standards are along this line.
A simple example of such a tip: use preincrement (++i) rather than postincrement (i++) when possible. This is especially important with iterators, as postincrement involves copying the iterator. You optimizer may be able to undo this, but it isn't any extra work to write preincrement instead, so why take the risk?
If I understand you correctly, you're asking about avoiding Premature Pessimization, a good complement to avoiding Premature Optimization. The #1 thing to avoid, based on my experience, is to not copy large objects whenever possible. This includes:
- pass objects by (const) reference to functions
- return objects by (const) reference whenever practical
- make sure you declare a reference variable when you need it
This last bullet requires some explanation. I can't tell you how many times I've seen this:
class Foo
{
const BigObject & bar();
};
// ... somewhere in code ...
BigObject obj = foo.bar(); // OOPS! This creates a copy!
The right way is:
const BigOject &obj = foo.bar(); // does not create a copy
These guidelines apply to anything larger than a smart pointer or a built-in type. Also, I highly recommend investing time learning to profile your code. A good profiling tool will help catch wasteful operations.
A few of my pet peeves:
- Don't declare (actually, define) object variables before their use/initialization (as in C). This necessitates that the constructor AND assigment operator functions will run, and for complex objects, could be costly.
- Prefer pre-increment to post-increment. This will only matter for iterators and user-defined types with overloaded operators.
- Use the smallest primitive types possible. Don't use a long int to store a value in the range 0..5. This will reduce overall memory usage, improving locality and thus overall performance.
- Use heap memory (dynamic allocation) only when necessary. Many C++ programmers use the heap by default. Dynamic allocations and deallocations are expensive.
- Minimize the use of temporaries (particularly with string-based processing). Stroustrup presents a good technique for defining the logical equivalent of ternary and higher-order arithmetic operators in "The C++ Programming Language."
- Know your compiler/linker options. Also know which ones cause non-standard behavior. These dramatically affect runtime performance.
- Know the performance/functionality tradeoffs of the STL containers (e.g., don't frequently insert into a vector, use a list).
- Don't initialize variables, objects, containers, etc., when they are going to be unconditionally assigned to.
- Consider the order of evaluation of compound conditionals. E.g., given
if (a && b)
, if b is more likely to be false, place it first to save the evaluation of a.
There are many other "bad habits" which I won't mention, because in practice, modern compilers/optimizers will eliminate the ill effects (for example, return value optimization vs. pass-by-reference, loop unwinding, etc.).