What is the optimization level g you use while comparing two different algorithms written in C?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
When comparing two algorithms in C or C++, the most important rule is not "pick one magic optimization flag." The important rule is to benchmark both implementations under the same realistic build settings, because compiler optimization can change the constant factors dramatically and can even erase code that is not used correctly in the benchmark.
Use Release-Level Optimizations, Not -O0
If the goal is algorithm performance, -O0 is usually the wrong choice. It is useful for debugging, but it does not represent how production code is typically built.
For most fair comparisons, start with -O2 or -O3 and use the same flags for both programs:
-O2 is a common default for honest performance testing because it applies strong optimizations without becoming as aggressive as -Ofast. -O3 can also be useful, especially if the production build uses it, but it may favor one implementation more than another because of inlining, vectorization, or loop transformations.
The key point is consistency: both algorithms must be compiled with the same toolchain and the same flags.
Match the Benchmark to the Intended Use Case
If the code will ship with -O3, benchmark with -O3. If the code will run in a normal release build with -O2, benchmark with -O2. The right flag is the one that matches the environment you care about.
A simple benchmark skeleton in C++ looks like this:
This is not a perfect microbenchmark, but it is good enough to illustrate the bigger issue: build flags affect the result.
Compare More Than One Optimization Level
In serious work, it is often worth testing more than one level:
- '
-O2for a conservative release comparison' - '
-O3for a more aggressive performance comparison' - '
-Ofastonly if relaxed language and floating-point rules are acceptable'
If one algorithm only wins under an extreme flag but loses under ordinary release settings, that is useful information. The benchmark should help you make a deployment decision, not just produce the prettiest number.
Keep Other Variables Fixed
Optimization level is only one part of a valid comparison. Keep these constant too:
- Compiler version
- Standard library implementation
- CPU architecture flags
- Input sizes and distributions
- Number of benchmark repetitions
If you compile one algorithm with -march=native and the other without it, or benchmark them with different data distributions, the comparison stops being meaningful.
Common Pitfalls
The biggest mistake is benchmarking with -O0 and then drawing conclusions about real-world speed. That mostly measures debug-build behavior, not algorithm performance.
Another common issue is letting the compiler optimize away work. If the benchmark computes something and never uses the result, the compiler may remove part of the algorithm entirely. Always consume the output in some visible way.
Developers also sometimes compare different code quality rather than different algorithms. If one implementation has unnecessary allocations, poor memory layout, or accidental copies, the benchmark may be measuring implementation mistakes more than algorithmic differences.
Finally, do not assume the fastest result under -Ofast is always the best engineering choice. That flag can change semantics in ways that are unacceptable for some numeric or standards-sensitive code.
Summary
- Use the same compiler and the same optimization flags for both algorithms.
- Benchmark release-style builds such as
-O2or-O3, not-O0. - Choose the optimization level that matches the way the code will actually be shipped.
- Test multiple optimization levels if the deployment target is uncertain.
- Control other variables so the benchmark measures the algorithms, not the environment.
Related reading
- What is the point of IDA vs A algorithm
- What is the probability that the array will remain the same?
- What is the problem name for Traveling salesman problemTSP without considering going back to starting point?
- What is the purpose of the visited set in Dijkstra?
- What is the overhead for creating multiple ZeroMQ sockets?
- What is the overhead of Javascript async functions
- What is the performance of stdatomic vs non-atomic variables?
- What is the relationship between BoostAsio and C20 coroutines?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.