It seems from your question that you already know about the "premature optimization is evil" philosophy, so I won't preach about that. :)
Modern compilers are already pretty smart at micro-optimizing things for you. If you try too hard, you can often make things slower than the original straight-forward code.
For small "optimizations" you can do safely without thinking, and which doesn't affect much the readability/maintability of the code, check out the "Premature Pessimization" section of the book C++ Coding Standards by Sutter & Alexandrescu.
For more optimization techniques, check out Efficient C++ by Bulka & Mayhew. Only use when justified by profiling!
For good general C++ programming practices, check out:
- C++ Coding Standards by Sutter & Alexandrescu (must have, IMHO)
- Effective C++/STL series by Scott Meyers
- Exceptional C++ series by Herb Sutter
Off the top of my head, one good general performance practice is to pass heavyweight objects by reference, instead of by copy. For example:
// Not a good idea, a whole other temporary copy of the (potentially big) vector will be created.
int sum(std::vector<int> v)
{
// sum all values of v
return sum;
}
// Better, vector is passed by constant reference
int sum(const std::vector<int>& v)
{
// v is immutable ("read-only") in this context
// sum all values of v.
return sum;
}
For a small object like a complex number or 2-dimensional (x, y) point, the function will likely run faster with the object passed by copy.
When it comes to fixed-size, medium-weight objects, it's not so clear if the function will run faster with a copy or a reference to the object. Only profiling will tell. I usually just pass by const reference (if the function doesn't need a local copy) and only worry about it if profiling tells me to.
Some will say that you can inline small class methods without thinking. This may give you a runtime performance boost, but it may also lengthen your compile time if there is a heavy amount of inlining. If a class method is part of a library API, it might be better not to inline it, no matter how small it is. This is because the implementation of inline functions has to be visible to other modules/classes. If you change something in that inline function/method, then other modules that reference it need to be re-compiled.
When I first started to program, I would try to micro-optimize everything (that was the electrical engineer in me). What a waste of time!
If you're into embedded systems, then things change and you can't take memory for granted. But that's another whole can of worms.