The Hacker News discussion revolves around the capabilities and limitations of modern optimizing compilers. Three dominant themes emerged:
1. The Compiler as an Oracle vs. Programmer Responsibility
There is a strong debate about the extent to which programmers should rely on the compiler to optimize code. While many accept that compilers handle micro-optimizations well, others argue that they fail on architectural or high-level algorithmic choices, reinforcing the idea that developers are still responsible for the fundamentals.
- Quotes:
- The initial premise: "I always code with the mindset 'the compiler is smarter than me.'" (jagged-chisel)
- A counterpoint asserting limits: "You are responsible for the algorithms, it is responsible for the code micro optimizations" (stonemetal12)
- Another user emphasizes architectural limitations: "They can't change your program architecture, algorithms, memory access patterns, etc." (IshKebab)
- A critique of blind faith: "That mindset will last until the first or second time you walk through the compiler's assembly-language output. ... if you do need to squeeze performance out of the processor, you can do a lot better than the compiler does." (kragen)
2. Data Structure and Memory Layout Matter More Than Micro-Optimizations
Several contributors stressed that optimizations related to data locality, structure layout, and memory access patterns often yield orders of magnitude better performance than micro-optimizations the compiler might miss. These high-level structural decisions are impossible for optimizers to infer safely.
- Quotes:
- "Optimizers generally don't change data structures or memory layout but that can make orders of magnitude difference in the performance of your program." (adrianN)
- "I am able to consistently and significantly improve on the performance of research code without any fancy tricks, just with good software engineering practices. By organising variables into structs, improving naming, using helper functions, etc..." (jaccola)
- "Once you set up a pointer-chasing data infrastructure changing that means rewriting most of your application." (adrianN)
3. Compiler Heuristics and Pass Ordering Lead to Missed Optimizations
Discussion frequently pointed out that compilers rely on a fixed sequence of heuristics (passes) rather than exhaustive searches. This leads to situations where mathematically equivalent code produces drastically different, and sometimes less optimal, assembly output because the intermediate representation does not match a known pattern for optimization.
- Quotes:
- Regarding struct unwrapping: "The magic seems to happen in your link at SROAPass, 'Scalar Replacement Of Aggregates'." (amiga386)
- Regarding why a simple conditional optimization fails: "The problem is that this problem really starts to run into the 'the time needed to optimize this isn't worth the gain you get in the end.'" (jcranmer)
- On why obvious mathematical equivalences are missed: "The compiler didn't recognize that x % 2 == 0 && x % 3 == 0 is exactly the same as x % 6 == 0 for all C/C++ int values." (senfiaj)