Don't judge performance based on a debug build
A debug build, especially in C++, contains a tremendous amount of checks and assertions. These checks and assertions are designed to make debugging easier. Essentially, a lot of operations check assumptions (pre-conditions, post-conditions, etc) in order to “fail fast” and display an error message as soon as something doesn’t seem right (e.g. some pre/post condition is violated). For example, when you try to access an element in an array, it will first check to make sure you are not accessing outside the bounds of the array.
While good for debugging, you need to ensure that you never profile and judge speed based on a debug build. All these checks and assertions, as well as a lack of optimizations, make debug builds run tremendously slower than non-debug builds.
Furthermore, when you really need speed, you can kinda follow this pattern of only adding excessive checks/assertions in your debug build. Conveniently, if you use the assert
macro in C++ to assert assumptions, these will automatically be removed from your non-debug builds.
So again, why are debug builds slow?
- checking assumptions (e.g. “is the array index out of bounds?”, “am I getting a negative value for age?”, etc) requires the CPU to do work. Sure this may not seem like a lot of work, and in most cases probably isn’t. However in performance critical areas of your code (e.g. really tight loops), they can make a huge dent.
- debug builds often have a lot of compiler optimizations turned off. Some compiler optimizations make it hard to map between source code and the binary, so debug builds disable these kind of optimizations. Otherwise, as you step through your code with the debugger, it would jump around.
- Debug builds have a lot of checks/assertions in the code, which make debugging easier, but significantly slow down the execution.
- When you are interested in profiling/judging the performance of your app, make sure that you are not profiling a debug build!
- If you are writing performance critical code, consider following the pattern of only adding checks/assertions in debug builds (e.g. in C++, use the
assert
macro)