本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4975474.html


今天我在优化公司项目代码的过程中,借助了Intel的VTune工具查看热点函数,发现有一个名为GetMatrixKey的函数调用频率很高,这个函数的主要作用是从一个矩阵数组中获取Matrix,其中还包含了指针检查与数组越界检查。考虑到这个函数的功能很简单,我就把它的实现挪到了头文件,并加上了inline关键字。随后我查看了一下这个函数的调用,发现它只在下面这个函数中被引用了(其中XXXX是类的名字,可以忽略掉):

// Author : 大便一箩筐 http://www.cnblogs.com/dbylk
D3DXMATRIX* XXXX::GetTransform(int nFrame) {
return GetMatrixKey(m_pTransform, m_nTransforms, nFrame);
}

我一看这个函数,马上就如法炮制,也把它挪进头文件,并加上了inline声明。

在继续进行了一些其他的优化后,我又运行了一下VTune,想要查看优化的结果。然后我惊奇地发现只有GetMatrixKey函数被内联了,GetTransform函数并没有被内联(VTune可以跟踪函数调用,如果函数被内联,则不会出现在函数的CPU利用列表中)。我记得当初学C++时,书上只是很笼统地说内联函数必须结构简单,但又没有定义什么才算“简单”函数。

随后,我去查了一下C++函数要满足什么条件才会被编译器内联,各个论坛中的人众说纷纭,下面是我整理粗略整理后得到的结果:

  • 函数体非常简单,通常为1~5行代码(这个应该不准确,因为我最开始被内联的那个函数就超过5行了,况且代码行数并不能和代码复杂度划等号)
  • 函数中不能包含循环语句、switch语句或异常处理语句(还有人说不能包含if语句,但经本人测试,包含if语句的函数是可以被内联的)
  • 函数中不能调用递归函数

然而,这些规则并不能解释GetTransform函数为什么没有被内联。随后,我又把GetMatrixKey函数取消内联,又进行了一次测试,结果发现GetTransform函数这一次被内联了,这说明内联函数A中可以调用其他函数B,但函数B不能是内联函数。

为此,我又采用了宏定义的方式实现GetTransform函数:

// Author : 大便一箩筐 http://www.cnblogs.com/dbylk
#define GetTransform(Key, nFrame) GetMatrixKey((Key).m_pTransform, (Key).m_nTransforms, nFrame)

结果发现GetTransform被“内联”(宏定义替换)了,GetMatrixKey函数没有被内联。

从上面的尝试可以得出一个结论,内联函数中不能包含其他内联函数,否则只有一个函数会被内联。


补充于2016-03-11:

内联函数可以说是用空间换时间的一种优化方式,因此它并不是一定能够提升程序性能的:如果一个实现比较复杂的函数可能在程序的很多个模块被调用,那么不内联可能会使程序具有更好的性能表现。因为内联会增加程序二进制代码的大小,这样会降低CPU Cache的命中几率,由此导致的开销可能远远超过内联优化得到的收益。

如果有足够的信心自己写的代码内联比不内联效率更高,可以使用C++的__forceinline关键字,这样一来编译器就会忽视优化选项,强制对函数执行内联处理。

关于inline函数的更多相关文章

  1. 理解C++的inline函数

    C++的inline函数就是编译器在编译代码时,将"对此函数的每一个调用"都以函数本体替换之,该过程发生在编译期间. inline函数的优点是,它可以省去函数调用所带来的额外开销, ...

  2. C++ inline函数

    本文主要记录了C++中的inline函数,也就是内联函数,主要记录了以下几个问题: C++为什么引入inline函数? 为什么inline能很好的取代表达式形式的预定义? inline函数的使用场合 ...

  3. inline函数的用法

    在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间或是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数.栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间 ...

  4. effective c++:inline函数,文件间编译依存关系

    inline函数 inline函数可以不受函数调用所带来的额外开销,编译器也会优化这些不含函数调用的代码,但是我们不能滥用Inline函数,如果程序中的每个函数都替换为inline函数那么生成的目标文 ...

  5. C++的优秀特性2:inline 函数

    (转载请注明原创于潘多拉盒子) Inline函数是C++的一个很小的特性,在不计较效率的情况下,这个特性似乎可有可无.然而,C++天生是为最为广泛的应用场景设计的,因此,总会有关于效率的问题.其实,除 ...

  6. 【转载】C++ inline 函数

    (一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...

  7. C++中的inline函数

    内联函数: () 内联函数定义和作用: 将一个函数声明为inline,那么函数就成为内联函数.内联函数通常就是它在程序中每个调用点上“内联地”展开.从定义上看,内联函数跟一般函数不一样,一般函数调用的 ...

  8. 【转载】 c语言inline函数的使用

    c语言inline函数的使用 转载自:http://blog.chinaunix.net/uid-21843265-id-3056446.html 大学在教科书上学习过inline函数,定义为inli ...

  9. C Static Inline函数

    Inline函数 程序执行时,处理器从Memory中读取代码执行.当程序中调用一个函数时,程序跳到存储器中保存函数的位置开始读取代码执行,执行完后再返回. 为了提高速度,C定义了inline函数,告诉 ...

  10. C++ inline 函数

    (一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...

随机推荐

  1. 深入Redis内部-Redis 源码讲解(转)

    Redis作为 NoSQL 数据库的杰出代表,一直广受关注,其轻量级的敏捷架构,向来有存储中的瑞士军刀之称.下面推荐的一篇文章,从源码的角度讲解了Redis 的整个工作流程,是了解 Redis 流程的 ...

  2. json的相关操作

    最近对json的操作不是很理解 定义: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式. 它基于 ECMAScript (w3c制定的j ...

  3. JDK源代码学习系列05----LinkedList

                                             JDK源代码学习系列05----LinkedList 1.LinkedList简单介绍 LinkedList是基于双向 ...

  4. 使用.gitignore忽略文件

    单个项目配置 在.git文件夹同目录下打开git bash,执行命令: touch .gitignore 生成“.gitignore”文件. 在”.gitignore” 文件里输入你要忽略的文件夹及其 ...

  5. redis.conf配置项说明

    #是否以后台进程运行,默认为no,如果需要以后台进程运行则改为yes daemonize no #如果以后台进程运行的话,就需要指定pid,你可以在此自定义redis.pid文件的位置. pidfil ...

  6. PL/SQL编程—包

    1.PLSQL 中的包就相当于java中的package,主要好处有(1)防止命名污染,(2)功能统一,(3)允许重载,(4)可以隐藏核心代码,(5)最重要的就是断开依赖链. 2.对于一个程序需要大量 ...

  7. hadoop18---socket实现rpc

    客户端: package cn.itcast_04_reflect.socket; import java.io.BufferedOutputStream; import java.io.Buffer ...

  8. 使用 getopt 处理命令行长参数

    getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令. getopt 与 getopts 的区别 getopts 是 shell 内建命令, getopt 是一个独立外 ...

  9. Java经纬读坐标的距离计算

    问题引出: 今天遇到经纬度坐标转换距离的工作,根据网站登录者的IP确定登录者目前的位置信息,将其经纬度信息与所有的营业厅的经纬度进行对比,网页上显示出距离登录者最近的营业厅地址,本打算就做一个二维坐标 ...

  10. 深入理解JVM4——线程安全

    浅谈java内存模型 不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序 ...