首页
登录 | 注册

C++之inline函数

        inline函数很潇洒,它看起来像函数,动作也像函数,但是调用它时又不需要蒙受函数调用所带来的额外开销,达到宏的性能而使用效果却好得多
        但是天下没有免费的午餐,inline函数在潇洒背后也有辛酸,inline函数的原理是编译器将“对此函数的每一个调用”都以函数本地替换之,由此可能带来的负面效应是增加目标码(object code)的大小。
        在一台内存有限的机器上,过度热衷inlining会造成程序体积太大,即使拥有虚拟内训,inline造成的代码膨胀亦会导致额外的换页行为(paging),降低指令高速缓存装置的命中率,以及伴随这些而来的效率损失。这一点尤其在目前炙手可热的移动开发来说很重要。
        换个角度说,如果inline函数的本体很小,编译器针对“函数本体”所产出的码可能比针对“函数调用”所产出的码更小,果真如此,将函数inlining确实可能导致较小的目标码和较高的指令高速缓存命中率。
        需要注意的是:inline只是对编译器的一个申请,而不是强制命令。这项申请可以隐喻提出,也可以明确提出。隐喻方式是将函数定义于class定义式内:
        class Person {
        public:
                ...
                int age() const {return theAge;}        //一个隐喻的inline申请,age被定义于class定义式内
                ...
        private:
                int theAge;
        };
        明确声明inline函数的做法则是在其定义式前加上关键字inline,例如标准的max template的实现就是:
        template
        inline const T& std::max(const T& a, const T& b)        //一个明确的inline申请,std::max之前有关键字“inline”
        { return a > b ? b : a;}
        大部分编译器拒绝将太过复杂(例如带有循环或递归)的函数inlining,而所有对virtual函数的调用(除非是最平淡无奇的)也都会使inlining落空,因为virtual意味着“等待,直到运行期才确定调用哪个函数”,而inline意味着“执行前,先将调用动作替换为被调用函数的本体”。如果编译器不知道该调用哪个函数,那就别怪它无情地拒绝将函数本体inlining了。但是也不要为此感到沮丧,幸运的是大多数编译器会在无法将你要求的函数inline化时给你一个警告信息,够哥们儿了。此外,对于通过函数指针调用的函数不会被inlining,因为编译器没有能力提出一个指针指向并不存在的函数。
        还是那句话天下没有免费的午餐,inline函数带来好处的同时也会有副作用:inline函数无法随着程序库的升级而升级。换句话说:如果某个函数f是程序库内的一个inline函数,客户将”f函数本体“编进其程序中了,一旦程序库设计者决定改变f,所有用到f的客户端程序都必须重新编译。如果f是non-inline函数,且在动态库中,则升级版函数会不知不觉地被应用程序吸纳。此外,有很多调试器不支持在inline函数中设置断点,因为此时函数并不存在。
        总结来了:将大不多数inlining限制在小型、被频繁调用的函数身上,这可使日后的调试过程和二进制升级更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。
      




        

相关文章

  •         这个条款其实就是宁可以编译器替换预处理器,因为#define不被视为语言的一部分,比如:         #define ASPECT_RATIO 1.653         在编译器处理源码前,ASPECT_RATIO就被 ...
  • 性能优化方法和技巧
    系列目录 性能优化方法和技巧性能优化的方法和技巧:概述性能优化的方法和技巧:代码性能优化的方法和技巧:工具 这是一个可以用一本书来讲的话题,用一系列博客来讲,可能会比较单薄一点,这里只捡重要的说,忽略很多细节,当然以后还可以补充和扩展这个话 ...
  • 这一节,接着讲 __atttribute__ 属性声明,__atttribute__ 可以说是 GNU C 最大的特色.我们接下来继续讲一下跟内联函数相关的两个属性:noinline 和 always_inline.这两个属性的用途是告诉编 ...
  • Node.js 回调函数 Node.js 异步编程的直接体现就是回调. 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了. 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数. ...
  • 内建函数,顾名思义,就是编译器内部实现的函数.这些函数跟关键字一样,可以直接使用,无须像标准库函数那样,要 #include 对应的头文件才能使用. 用来处理变长参数列表: 用来处理程序运行异常: 程序的编译优化.性能优化: 查看函数运行中 ...
  • 实验环境:CentOS 6.7 1. 安装Ruby CentOS 6.7中默认安装的是Ruby 1.8,安装最新版2.2.3. root [ ~ ]# wget https://cache.ruby-lang.org/pub/ruby/2. ...

2019 unjeep.com webmaster#unjeep.com
12 q. 0.025 s.
京ICP备10005923号