C++内联使用技巧
2013-12-06 16:42
260 查看
内联的总结:
使用条件:短小,调用频繁的函数
内联的缺点:增加了编译的时间,不便于调试
内联的优点:避免了函数调用带来的开销,同时为编译器进一步优化提供可能(调用间的优化编译器一般无能为力,但是内联后编译器可以进一步优化)。对于一些微小的方法内联(一般就是几条指令),可以减少最终的可执行文件(因为调用开销也需要一些指令的)
内联不当的后果:造成代码膨胀,导致与性能相关的方负面影响:缓存失败和页面错误。(缓存与页面大小固定,代码膨胀以及内联的方法可能存在多个地址,这些都导致缓存或页面不足,频繁的切换的可能性大大提高。)
内联技巧:
1、条件内联
内联增加编译时间,并且不便于调试,而产品发布时,希望内联以增加性能,此时可以采用条件内联。使用方式如下:
x.h
#ifndef _X_H
#define _X_H
class A
{
void y();
};
#if defined(INLINE)
#include "x.inl"
#endif
#endif
x.inl
#if !defined(INLINE)
#define inline
#endif
inline void A::y(){}
x.cpp
#if !defined(INLINE)
#include "x.inl"
#endif
2、选择内联
由于对非短小但频繁的代码内联可能造成代码膨胀,此时我们希望只对在核心路径上的调用内联,而其他不内联,此时我们可以采用如下方式:
对该方法创建两个不同的接口名,其中一个接口调用内联的接口名,核心路径上的调用,则使用内联的接口名,非核心路径上使用非内联接口名。如:
#ifndef _X_H
#define _X_H
class A
{
void y();
void inline_y();
};
#if defined(INLINE)
#include "x.inl"
#endif
#endif
x.inl
#if !defined(INLINE)
#define inline
#endif
inline void A::inline_y(){...}
x.cpp
#include "x.h"
void A::y()
{
inline_y();
}
3、递归内联
一般情况下,内联不能使用在递归上。这里的递归不是传统意义上的递归,这里是手动展开几层,然后再递归调用
如在二叉树查找中中序遍历的递归操作如下:(有些内容省了)
void binary_tree::key_out()
{
if(left) left->key_out();
cout << id << endl;
if(right) right->key_out();
}
使用内联递归的方法:
inline void binary_tree:INLINE_key_out()
{
if(left) left->key_out();
cout << id << endl;
if(right) right->key_out();
}
void binary_tree::key_out()
{
if(left) left->INLINE_key_out();
cout << id << endl;
if(right) right->INLINE_key_out();
}
使用条件:短小,调用频繁的函数
内联的缺点:增加了编译的时间,不便于调试
内联的优点:避免了函数调用带来的开销,同时为编译器进一步优化提供可能(调用间的优化编译器一般无能为力,但是内联后编译器可以进一步优化)。对于一些微小的方法内联(一般就是几条指令),可以减少最终的可执行文件(因为调用开销也需要一些指令的)
内联不当的后果:造成代码膨胀,导致与性能相关的方负面影响:缓存失败和页面错误。(缓存与页面大小固定,代码膨胀以及内联的方法可能存在多个地址,这些都导致缓存或页面不足,频繁的切换的可能性大大提高。)
内联技巧:
1、条件内联
内联增加编译时间,并且不便于调试,而产品发布时,希望内联以增加性能,此时可以采用条件内联。使用方式如下:
x.h
#ifndef _X_H
#define _X_H
class A
{
void y();
};
#if defined(INLINE)
#include "x.inl"
#endif
#endif
x.inl
#if !defined(INLINE)
#define inline
#endif
inline void A::y(){}
x.cpp
#if !defined(INLINE)
#include "x.inl"
#endif
2、选择内联
由于对非短小但频繁的代码内联可能造成代码膨胀,此时我们希望只对在核心路径上的调用内联,而其他不内联,此时我们可以采用如下方式:
对该方法创建两个不同的接口名,其中一个接口调用内联的接口名,核心路径上的调用,则使用内联的接口名,非核心路径上使用非内联接口名。如:
#ifndef _X_H
#define _X_H
class A
{
void y();
void inline_y();
};
#if defined(INLINE)
#include "x.inl"
#endif
#endif
x.inl
#if !defined(INLINE)
#define inline
#endif
inline void A::inline_y(){...}
x.cpp
#include "x.h"
void A::y()
{
inline_y();
}
3、递归内联
一般情况下,内联不能使用在递归上。这里的递归不是传统意义上的递归,这里是手动展开几层,然后再递归调用
如在二叉树查找中中序遍历的递归操作如下:(有些内容省了)
void binary_tree::key_out()
{
if(left) left->key_out();
cout << id << endl;
if(right) right->key_out();
}
使用内联递归的方法:
inline void binary_tree:INLINE_key_out()
{
if(left) left->key_out();
cout << id << endl;
if(right) right->key_out();
}
void binary_tree::key_out()
{
if(left) left->INLINE_key_out();
cout << id << endl;
if(right) right->INLINE_key_out();
}