Programming Tips & Tricks

Home Categories: C# | C++ | General | Other

General Programming Tips & Tricks: Code Performance Tips

General Tips
These tips are the most important, and are applicable to all languages

1. Prefer high-level over low-level optimizations
This is the most important tip: when trying to increase program performance, start with your algorithms and data structures. High-level optimization using a Hashmap with O(1) complexity for element retrieval instead of a O(n) List in a program that continually needs to read elements from a data storage, or using quicksort instead of bubblesort in a program that has to do a lot of sorting, will increase program performance much, much more than low-level optimizations like substituting a divide by a multiply somewhere.
2. Optimize for the common case
Even a small improvement in a method that is called a thousand times a second will be much more worth than a larger (and more developer-time consuming) inmprovement in a method that is only called once a second.
3. Know your data
This goes hand in hand with the first two tips. Try to have a good knowledge of how your program's data will look, so you know how and where to best optimize your program. Knowing the size and distribution of data sets can help choosing the optimal algorithms and data structures to use with them. For example, some algorithms that are slow for large data sets, are actually better than other algorithms when the data set is very small.
4. Profile
This helps you to optimize for the common case. Run your program through a profiler, to find the bottlenecks, and to find out where your program spends the most time, so you know where optimization efforts will yield the greatest gain.
5. Know your language
If you want to achieve maximum performance, you must not only know your language enough to code in it, but you must know it good enough to make the best choices. For example when you use C#, know when boxing/unboxing occurs to save costs, know the cost of operations on different built-in types (e.g. don't use decimal if you need speed), know when implicit conversions lead to the creation of temporary objects, know how the garbage collector works, etc.
6. Test
Never simply trust that a change you made actually improves performance, even if it should. There might be side-effects that actually decrease performance. After you make a change you think will be good, test if it really is. If you're not sure which of two or more possibilities is the best, test them all. And make sure you test with real-world data, as simplistic test data might invalidate test results.
7. Use the right tool for the job
Consider using a lower-level language. You don't have to switch your whole program to a different language, but if you are unsatisfied with program performance, you can rewrite critical parts for example in C, and compile them to a DLL you call from your program.
8. Use available software
Most languages come with good libraries and frameworks (STL, boost, .Net, etc). Know them and use them wherever you can. Reinventing the wheel by implementing algorithms or data structures available in those libraries yourself doesn't only cost time, but chances are good that the library's implementation will be faster, since usually a lot of time is spent by the developers/vendors to optimize those libraries.
And if your needs are more special than what the standard libraries support, consider looking for available libraries for your specific needs.
9. Multithread
Increase performance by running blocking tasks, like extensive file IO, in their own threads, and don't run heavy calculations in the same thread as your GUI.
Today most processors have multiple cores or support some concept like hyperthreading, which you can use to your advantage by parallelizing your code to run multiple calculations at the same time, or even parallelizing your algorithms. This is neither easy nor possible for every algorithm, but it might be well worth your time. Also, some language's libraries help alot with it. For example, in C# some LINQ queries can be sped up almost 100% per additional cpu core by using PLINQ instead, which only requires you to add .AsParallel() to a query.
10. Use the hardware
Using the available hardware to your best advantage already includes the last point, leveraging all cpu cores. Another point here concerns you if you do extensive graphics. In that case, use the GPU to your maximum advantage. Know the ins and outs of your graphics API (DirectX, OpenGL) and some shader language, so you can let the GPU perform transformations and lightning via shaders, so the CPU is freed up for other tasks. Lately, since the shader's abilities have improved, they can even be used for non-graphical tasks, like array sorting.
Audio is another area where you can let the soundcard handle some tasks through libraries like DirectX or OpenAL, to free the CPU for other tasks.

Specific Tips
These tips are more dependent on language and compiler. They should improve performance in many cases, but might not always have an effect

1. Write frequent case lables first, so execution can skip as many tests as possible
2. Minimize the number of local variables, so that all can be kept in registers
3. Make array sizes powers of two, so the compiler can index with bit-shift instead of multiply
4. Exceptions are expensive. Don't overuse them in performance critical sections of your code
5. Declare variables in the innermost scope
6. Small structs are faster (and require less space) than small classes
7. Never pass structs by value
8. Writing to a class member is more expensive than writing to a local variable (so don't do it in inner loops; this is especially important in languages like C#, where a class member could be a property, and value assignment could include execution of a setter method)
9. Avoid tests and branches where possible
10. Return from a method at the earliest possible opportunity
11. Avoid method calls in inner loops. Jumping to another function ruins the cache
12. Avoid LHS (load hit store): writing to a heap address and immediately reading it stalls the processor, since he might have to wait until the value passed through cache and was written to ram, before reading it back is possible
13. Don't do expensive argument construction for a method that might not use the argument (for example, don't call Log(s1+s2+s3+s4) if Log checks for debug mode in its first line and only then continues. In this case, the string concatenation s1+s2+s3+s4 is also done for release builds, even though its never used)
14. Replace modulo operations with values that are a power of two with bitwise operators (e.g. x % 16 is equivalent to x & 15) and you are not sure if your compiler will do such optimizations
15. Re-initializing objects is cheaper then copying or initializing new objects
16. Virtual methods are bad for performance. The class will gain an additional vtable, making it larger, and each method call will include an additional check to resolve the correct method implementation
17. Before running expensive code inside some update/refresh method, check if the value has actually changed and the code needs to be run
18. Make small functions inline

Other Tips

1. When you use a database, make sure your tables use an index (or more than one)
2. If your SQL query references anything in the outer query from an inner query, change it!