关于inline函数
本文为大便一箩筐的原创内容,转载请注明出处,谢谢: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函数的更多相关文章
- 理解C++的inline函数
C++的inline函数就是编译器在编译代码时,将"对此函数的每一个调用"都以函数本体替换之,该过程发生在编译期间. inline函数的优点是,它可以省去函数调用所带来的额外开销, ...
- C++ inline函数
本文主要记录了C++中的inline函数,也就是内联函数,主要记录了以下几个问题: C++为什么引入inline函数? 为什么inline能很好的取代表达式形式的预定义? inline函数的使用场合 ...
- inline函数的用法
在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间或是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数.栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间 ...
- effective c++:inline函数,文件间编译依存关系
inline函数 inline函数可以不受函数调用所带来的额外开销,编译器也会优化这些不含函数调用的代码,但是我们不能滥用Inline函数,如果程序中的每个函数都替换为inline函数那么生成的目标文 ...
- C++的优秀特性2:inline 函数
(转载请注明原创于潘多拉盒子) Inline函数是C++的一个很小的特性,在不计较效率的情况下,这个特性似乎可有可无.然而,C++天生是为最为广泛的应用场景设计的,因此,总会有关于效率的问题.其实,除 ...
- 【转载】C++ inline 函数
(一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...
- C++中的inline函数
内联函数: () 内联函数定义和作用: 将一个函数声明为inline,那么函数就成为内联函数.内联函数通常就是它在程序中每个调用点上“内联地”展开.从定义上看,内联函数跟一般函数不一样,一般函数调用的 ...
- 【转载】 c语言inline函数的使用
c语言inline函数的使用 转载自:http://blog.chinaunix.net/uid-21843265-id-3056446.html 大学在教科书上学习过inline函数,定义为inli ...
- C Static Inline函数
Inline函数 程序执行时,处理器从Memory中读取代码执行.当程序中调用一个函数时,程序跳到存储器中保存函数的位置开始读取代码执行,执行完后再返回. 为了提高速度,C定义了inline函数,告诉 ...
- C++ inline 函数
(一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...
随机推荐
- pop 在列表中和字典中的区别
pop 在列表中和字典中的区别 字典中 pop() 语法:dict.pop(key,[value]) 说明:删除指定键及对应的值,如果在字典中不存在键及value,则返回pop()中指定的key对应的 ...
- Python高级教程-切片
Python中的切片 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>> L = ['A','B','C','D'] 对经常取指定索引范围的操作, ...
- 全球第一张中文网络协议分析图——By 成都科来软件
网上内容比较全面的网络协议图并不是很多,这些网络协议图大多只遵循OSI,对于TCP/IP基本不支持,有些协议图表示也不够准确.另一方面,现在网上能找到的协议图全都是英文版本,使用起来不是很方便.国内的 ...
- Android View学习Tips
1.Canvas.save()和Canvas.restore() canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的.这里 ...
- 修改 item2 用户名
首先在命令行输入 cd .oh-my-zsh/themes 如下图: 然后命令行输入 sudo vi agnoster.zsh-theme 如下图: 最后在编辑主题文件 在 prompt_segmen ...
- 深入ff and ffbase
用ff 包读取一个csv 文件 >options(fftempdir = [二进制文件存放的位置]) >file_chunks <- read.csv.ffdf(file=”big_ ...
- linux 或c 时间相关处理类型和函数
注意1.精确级别,纳秒级别原型long clock_gettime (clockid_t which_clock, struct timespec *tp); 头文件time.hwhich_cloc ...
- Java集合(3):Vector && Stack
一.Vector介绍 Vector可以实现可增长的动态对象数组.与数组一样,它包含可以使用整数索引进行访问的组件.不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删 ...
- CodeForces - 451E Devu and Flowers (容斥+卢卡斯)
题意:有N个盒子,每个盒子里有fi 朵花,求从这N个盒子中取s朵花的方案数.两种方法不同当且仅当两种方案里至少有一个盒子取出的花的数目不同. 分析:对 有k个盒子取出的数目超过了其中的花朵数,那么此时 ...
- Winform ObservableCollection 添加删除修改无效
WPF中ObservableCollection 可以很好的使用. 在Winform中,之前使用ObservableCollection 做了几个功能,貌似增删改都可以. 今天写个Demo的时候发现不 ...