我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
当前回答
在决定是否使用内联时,我通常记住以下想法:在现代机器上,内存延迟可能是比原始计算更大的瓶颈。众所周知,经常调用的内联函数会增加可执行文件的大小。此外,这样的函数可以存储在CPU的代码缓存中,当需要访问代码时,这将减少缓存失败的数量。
因此,您必须自己决定:内联是否会增加或减少生成的机器代码的大小?调用该函数会导致缓存丢失的可能性有多大?如果它遍布整个代码,那么我认为可能性很高。如果它被限制在一个单一的紧密循环,那么可能性很低。
我通常使用内联的情况下,我列出如下。然而,当您真正关心性能时,概要分析是必不可少的。此外,您可能希望检查编译器是否真的接受了提示。
在紧密循环中调用的简短例程。 非常基本的访问器(get / set)和包装器函数。 不幸的是,头文件中的模板代码会自动获得内联提示。 像宏一样使用的短代码。(例如min() / max()) 简短的数学程序。
其他回答
告诉编译器内联函数是一种优化,而最重要的优化规则是过早的优化是万恶之源。始终写清晰的代码(使用高效的算法),然后分析你的程序,只优化那些花费太长时间的函数。
如果您发现一个特定的函数非常简短,并且在一个紧凑的内部循环中被调用了数万次,那么它可能是一个很好的候选者。
不过,您可能会感到惊讶——许多c++编译器会自动为您内联小函数——而且它们可能也会忽略您的内联请求。
此外,在维护大型项目时,内联方法有严重的副作用。当内联代码被更改时,所有使用它的文件将由编译器自动重建(如果它是一个好的编译器)。这可能会浪费大量的开发时间。
当内联方法被传输到源文件而不再内联时,整个项目必须重新构建(至少这是我的经验)。当方法转换为内联时也是如此。
只有当函数代码很小时,才应该使用内联函数限定符。如果函数比较大,则应该使用普通函数,因为节省内存空间可以换取相对较小的执行速度牺牲。
我通常遵循一个拇指规则,我用3-4个简单的语句作为内联函数。但最好记住,这只是给编译器的一个提示。最终是否使它内联的调用仅由编译器执行。如果有超过这些语句,我不会用一个愚蠢的编译器进行内联声明,这可能会导致代码膨胀。
内联函数可以通过消除将参数推入堆栈的需要来提高代码性能。 如果有问题的函数在你的代码的关键部分,你应该在项目的优化部分做出内联而不是内联的决定,
你可以在c++ FAQ中阅读更多关于内联的内容