Skip to content
📖 Auto 版 Modern C本书目录

第十六章:性能 ​

级别 3 — 经验

内联函数、restrict 限定符和性能测量——榨取 C 的每一个周期,以及 Auto 如何为你处理优化。

性能很重要。不是每个程序都需要,也不是每时每刻都需要,但当它重要时,C 程序员需要理解如何编写快速代码以及如何证明代码是快的。C 通过 inline 和 restrict 等关键字、编译器属性和精确测量为你提供对性能的细粒度控制。Auto 采取不同的方法:编译器处理大多数优化,你专注于编写清晰的代码。


16.1 内联函数 ​

C 的 inline 关键字向编译器建议将函数体直接替换到调用点,避免函数调用的开销:

c
// C 深入:内联函数
static inline int square(int n) {
    return n * n;
}

static inline int max(int a, int b) {
    return (a > b) ? a : b;
}

C 中 inline 的规则微妙且经常被误解:

  • inline 本身不保证内联——它只是一个提示。
  • 在头文件中定义的 inline 函数需要在一个翻译单元中有对应的外部定义,否则程序具有未定义行为(C99/C11)。
  • static inline 是实际的解决方案:每个翻译单元都有自己的副本,链接器不会看到重复符号。
  • 编译器可以完全忽略 inline。现代编译器经常内联没有标记 inline 的函数,而拒绝内联标记了的函数。

C 深入: C 中 inline 与链接之间的交互是语言中最令人困惑的方面之一。C99 引入了具有外部链接语义的 inline,与 C++ 不同。在实践中,大多数 C 程序员在头文件中使用 static inline,避免这种复杂性。C23 通过使 inline 行为更像 C++ 来简化了这一点。

Auto 的方法。 Auto 没有 inline 关键字。编译器根据启发式算法自动决定内联:

  • 小函数总是被内联。
  • 在热循环中调用的函数是内联候选。
  • 程序员可以标注性能关键的函数,但编译器做最终决定。
auto
// Auto:不需要 inline 关键字
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))
}

基于 MIT 许可发布。