Get someone else to do it
The thing about programme optimization is that
you don't have to do it yourself, most of the time: a good
compiler is likely to be able to optimize far better than you will, except with the most
extreme effort. Try to keep the
code clean, and avoid doing things that will frustrate
compiler optimization, such as manually forcing
memory allocation strategies, writing non-
tail-recursive code when
tail-recursion would be just as good, and so-on. Of course, if you use a
declarative (or decent
imperative) language, you're likely to get a much smarter compiler than if you're using
C++.
Even if you're using a fairly crappy language like java, with a "clever" VM, the virtual machine will execute well-compiled bytecode faster. Try different compilers to see what they provide.
If your programme isn't running fast enough, use a
profiler to discover where most of your execution time is spent BECAUSE YOUR
INTUITION IS WRONG OR YOUR MONEY BACK. Also, discover WHY. Will more RAM, faster processors, or faster IO help? More RAM is often key; IO can rarely be directly improved, but simple strategies may help, and processor bound computations often indicate that a more efficient algorithm exists.
Know your enemy
Your enemy falls into two groups: Stylistic failures, and strategic failures.
Stylistic failures
This comprises things like excessive
heap allocation and recursion of small
stack-frames while using a compiler that cannot optimise this for you.
In general, you can make mileage out of aggregating many small, costly operations into one, single, larger operation. This is exemplified by buffered IO, eagerly allocating enough memory for the whole computation at one time, and so-on.
Your second weapon is replacing costly operations (e.g. multiplications or sorts) with appropriate alternatives, such as additive algorithms, or linear scans. In this vein, you may wish to use non-blocking (threaded) IO, so that you are not wasting time.
Both of these will be aided by using appropriate data structures. Do not use arrays for anything unless you really know what you are doing.
Strategic failures
These tend to require the use of external help: Try to use a
garbage collector if you don't have one, and if you do, try to provide what hints you can. If you are creating a resource-bound programme you may benefit from disabling garbage collection, and doing it yourself, or using a garbage collector with a fixed strategy that works very well in your programme, but would suck for larger programmes. READ THE MANUAL. Alternatively, you may be eagerly evaluating things that are often discarded. You may wish to use some kind of
lazy or
symbolic computation engine, or if your computation is probabilistic STOP USING A
HEURISTIC YOU MADE UP IN ONE MOMENT BEFORE RUSHING TO THE TOILET. Use a standard heuristic, or a principled methodology, possibly using a function-generator, such as a perfect
hash-function generator.
It is important to know the costs involved in invoking third-party libraries.
In conclusion
Use the learning and effort of clever people to hide the fact that you are lazy and stupid (or at least stupider than they, and don't have years to perfect this damn programme). If this doesn't work, try calculating the cost of buying more RAM (or CPU if it really is a processor-bound computation), versus the increased cost of your time. If you
are industrious and fantastically clever, you don't need my advice.