inline 函数——多么棒的主意啊!它们看起来像函数,它们产生的效果也像函数,它们在各方面都比宏好得太多太多,而你却可以在调用它们时不招致函数调用的成本。你还有什么更多的要求呢?
实际上你得到的可能比你想的更多,因为避免函数调用的成本只是故事的一部分。在典型情况下,编译器的优化是为了一段连续的没有函数调用的代码设计的,所以当你 inline 化一个函数,你可能就使得编译器能够对函数体实行上下文相关的特殊优化。大多数编译器都不会对 “outlined” 函数调用实行这样的优化。
然而,在编程中,就像在生活中,没有免费午餐,而 inline 函数也不例外。一个 inline 函数背后的思想是用函数本体代替每一处对这个函数的调用,而且不必拿着统计表中的 Ph.D. 就可以看出这样可能会增加你的目标代码的大小。在有限内存的机器上,过分热衷于 inline 化会使得程序对于可用空间来说过于庞大。即使使用了虚拟内存,inline 引起的代码膨胀也会导致附加的分页调度,减少指令缓存命中率,以及随之而来的性能损失。
在另一方面,如果一个 inline 函数本体很短,为函数本体生成的代码可能比为一个函数调用生成的代码还要小。如果是这种情况,inline 化这个函数可以实际上导致更小的目标代码和更高的指令缓存命中率! 记住,inline 是向编译器发出的一个请求,而不是一个命令。这个请求能够以显式的或隐式的方式提出。隐式的方法就是在一个类定义的内部定义一个函数:
class Person { public: … int age() const { return theAge; } // an implicit inline request: age is … // defined in a class definition private: int theAge; }; |
这样的函数通常是成员函数,不过我们知道友元函数也能被定义在类的内部,如果它们在那里,它们也被隐式地声明为 inline。
显式的声明一个 inline 函数的方法是在它的声明之前加上 inline 关键字。例如,以下就是标准 max 模板(来自
template inline const T& std::max(const T& a, const T& b) // request: std::max is { return a < b ? b : a; } // preceded by “inline” |
>> 本文固定链接: http://www.vcgood.com/archives/805