Chapter 16: Performance
Level 3 — Experience
Inline functions, restrict qualifiers, and measurement -- squeezing every cycle out of C, and how Auto handles optimization for you.
Performance matters. Not for every program, and not at every moment, but when it matters, C programmers need to understand how to write fast code and how to prove that their code is fast. C gives you fine-grained control over performance through keywords like inline and restrict, through compiler attributes, and through careful measurement. Auto takes a different approach: the compiler handles most optimizations, and you focus on writing clear code.
16.1 Inline Functions
The C inline keyword suggests to the compiler that a function's body should be substituted directly at the call site, avoiding the overhead of a function call:
// C Deep Dive: inline functions
static inline int square(int n) {
return n * n;
}
static inline int max(int a, int b) {
return (a > b) ? a : b;
}The rules for inline in C are subtle and frequently misunderstood:
inlinealone does not guarantee inlining -- it is a hint.- An
inlinefunction defined in a header needs a corresponding external definition in exactly one translation unit, or the program has undefined behavior (C99/C11). static inlineis the practical solution: each TU gets its own copy, and the linker sees no duplicate symbols.- Compilers are free to ignore
inlineentirely. Modern compilers often inline functions that are not markedinlineand refuse to inline functions that are.
C Deep Dive: The interaction between
inlineand linkage in C is one of the most confusing aspects of the language. C99 introducedinlinewith external linkage semantics that differ from C++. In practice, most C programmers usestatic inlinein headers and avoid the complexity. C23 simplifies this by makinginlinebehave more like C++.
Auto's approach. Auto does not have an inline keyword. The compiler decides inlining automatically based on heuristics:
- Small functions are always inlined.
- Functions called in hot loops are candidates for inlining.
- The programmer can annotate performance-critical functions, but the compiler makes the final decision.
// Auto: no inline keyword needed
fn square(n int) int {
n * n
}
fn max(a int, b int) int {
if a > b { a } else { b }
}
fn main() {
print("square(7) =", square(7))
print("max(3, 7) =", max(3, 7))
}