[Effective C++系列]-透彻了解inlining的里里外外
- [原理]
- 可以消除函数调用所带来的开销。
- 编译器最优化机制通常被设计用来浓缩那些“不含函数调用”的代码,因此当你inline某个函数,或许编译器有能力对它(函数本体)执行语境相关最优化。大部分编译器不会为一个“outlined函数调用”执行这种最优化动作。
- 当你申请(隐式或者显式)对一个函数进行inlining时,编译器未必真的这么做了,编译器自己会根据具体情况作出判断。
- 有些你没注意到的写法可能导致一个函数被隐式inlining,例如将函数的声明和实现均放在头文件中。
- [详解]
class person
{
public:
...
int age() {return m_age;} // 该函数会被隐式申请为inline函数
...
private:
int m_age;
};
这样的函数通常是成员函数,但是如果把friend函数的实现也放在头文件内,那么该friend函数也会被隐式申请为inline。
例如:
class dummy
{
public:
explicit dummy(int i) : m_data(i)
{}
private:
int m_data; friend void swap(dummy& lhs, dummy& rhs)
{
int temp = lhs.m_data;
lhs.m_data = rhs.m_data;
rhs.m_data = temp;
}
};
template <typename T>
inline const T& max(const T& a, const T& b)
{return a >b ? a : b;}
inline void fn() {…} // 假设编译器愿意inline“对fn的调用”
void (*pf) () = fn; // pf指向fn
...
fn(); // 该调用会被inlined,因为这是一个正常调用。
pf(); // 该调用不会被inlined, 因为它是通过函数指针实施。
- [总结]
- 一个合乎逻辑的策略是:一开始不要讲任何函数声明为inline,或至少将inlining局限于小型的、被频繁调用的函数身上。这会使得日后的调试和二进制升级更容易,也可使代码膨胀的问题最小化,使程序的速度提升机会最大化。
- 不要只因为function template出现在头文件中,就将它们声明为inline。
- [补充]
From:http://www.cnblogs.com/xkfz007/archive/2012/03/27/2420166.html
不恰当地使用inline导致编译器拒绝进行inlining是会带来副作用的,这会带来代码膨胀(目标码膨胀)和可能极难察觉的bug。因为编译器对普通函数(没有声明为inline)的实现与对inlining失败的函数的实现是不同的。
普通函数在编译时被单独编译为一个对象,包含在相应的目标文件中。目标文件在链接时,对该函数的调用会被链接到该对象上。
若一个函数被声明为inline,那么编译器即使遇到该函数的声明也不会为该函数编译一个对象,因为inline函数是在调用的地方进行展开的。但是如果在调用的地方发现该inline函数不适合被展开怎么办?一种做法是在调用该内联函数的目标文件中为该内联函数编译一个对象。这么做的直接后果是:若在多个文件调用了内联失败的函数,其中每个文件对应的目标文件中都会包含一份该内联函数的目标代码。
如果编译器真的选择了上面的做法对待内联失败的函数,那么目标代码的体积膨胀得与成功内联的目标代码一样,但目标代码的效率确和没内联一样。
更糟的是由于存在多份函数目标代码带来一些程序bug。最明显的例子是:内联失败的函数内的静态变量实际上就不在只有一份,而是有若干份。这显然是个错误,但是如果不了解内幕就很难找到原因。
[Effective C++系列]-透彻了解inlining的里里外外的更多相关文章
- [Effective C++ --030]透彻了解inlining的里里外外
引言 inline函数 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数.与非inline函 ...
- Effective C++ -----条款30:透彻了解inlining的里里外外
将大多数inlining限制在小型.被频繁调用的函数身上.这可使日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化 ...
- 【30】透彻了解inlining 的里里外外
1.inline方法相当于文本替换,不需要承担方法调用的额外开销,同时还有潜在的优势,文本替换后,编译器会进行代码优化.而对于方法调用,编译器没有能力进行代码优化. 2.显而易见,inline方法往往 ...
- 条款30:透彻了解inline的里里外外(understand the ins and outs of inlining)
NOTE: 1.将大多数inline限制在小型 被频繁调用的函数身上.这可使日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化, 使程序的速度 ...
- Effective java 系列之避免过度同步和不要使用原生态类型,优先考虑泛型
避免过度同步(67):在一个被同步的方法或代码块中,不要调用哪些被设计成被覆盖的方法或者是由客户端以函数对象的形式提供的方法(21). 有点拗口,书上提供的创建者与观察者模式,add方法太多,看得眼花 ...
- [Effective C++系列]-为多态基类声明Virtual析构函数
Declare destructors virtual in polymorphic base classes. [原理] C++指出,当derived class对象经由一个由base clas ...
- Effective java 系列之异常转译
异常转译:当位于最上层的子系统不需要关心底层的异常细节时,常见的作法时捕获原始异常,把它转换一个新的不同类型的异常,在将新异常抛出. 通常方法捕获底层异常,然后抛高层异常. public static ...
- Effective java 系列之更优雅的关闭资源-try-with-resources
背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...
- 条款30:透彻了解inline的里里外外。
inline可以带来各种好处: 首先其可以使得消除函数调用带来的开销,再者编译器对这种非函数的代码可以做出更多的优化策略. 但是inline函数首先肯定是会导致程序代码的大小更加的庞大,这样会带来 ...
随机推荐
- DWZ在APS.NET WebForm中的使用(二)
任何框架由于个人理解不到位或者框架自身的局限性,在项目实施中,大家或多或少都会遇到一些问题,下面我就讲述下我在使用DWZ开发过程中的几个问题.如有一点能帮助到你,这篇文章也算有存在的意义了. 1.树菜 ...
- Windows环境搭建Red5流媒体服务器指南(转)
Windows环境搭建Red5流媒体服务器指南 Windows环境搭建Red5流媒体服务器指南 测试环境:Windows 7 一. 下载安装程序 red5-server 下载地址 https:// ...
- JMS & ActiveMQ小结
JMS简介 JMS源于企业应用对于消息中间件的需求,使应用程序可以借助消息进行异步处理而互不影响.Sun公司和它的合作伙伴设计的JMS API定义了一组公共的应用程序接口和相应语法,使得Java程序能 ...
- [转]C语言的那些秘密之---函数返回局部变量
一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了.因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错.但是如果返回的是局部变量的地 ...
- View的工作原理(二)——layout
1.当View的measure被确定后,会调用ViewGroup的layout方法,之后使用onLayout方法(同样也是系统未自动重写,要我们自己完成)遍历子View(根Measure的形式是一样得 ...
- python运维开发(十一)----python操作缓存memcache、redis
内容目录: 缓存 memcache redis memcache Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数 ...
- flask-script 安装问题
> 昨天开始看 flask,第二章最后提到使用 Flask-Script 支持命令行选项,但是用书上的方法安装却出现了问题. 错误信息: 注意最后两行: Could not find a ver ...
- 变形课--hdu1181
变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submis ...
- android 管理Bitmap内存 - 开发文档翻译
由于本人英文能力实在有限,不足之初敬请谅解 本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接 Managing Bitmap Memory 管理Bitmap内存 In additi ...
- 第3.3.4节 创建高级图形之RenderScript(二)
Android视图框架对于创建复杂布局非常方便.然而,这种便利是以性能为代价的.当性能至关重要的时候,Android提供了几种更强大的图形处理能力,当然难度也是随之上升了.在本节中,我将介绍: ...