最近在考虑函数速度的优化问题。一般函数分为普通函数和inline函数,因为既然inline是编译器展开,那么我何不手动展开试试呢。在频繁访问数据的情况下,他们各自的速度对比是怎样的?
通常情况,inline比普通调用要快,但是,如果我是通过对象A调用访问对象B的数据呢?普通函数相对inline真的慢?inline手动展开了,要好几次访问B,然后再访问数据;而普通的调用,只需要访问一次B的调用;手动展开了,会不会比编译器展开的快呢,而且或许还可以做些手动优化。
以下用了一个很简单的例子,做了一个简要的测试。
#include<cstdio>;
#include <windows.h>
#pragma comment( lib,"winmm" )
#define C 10*1000*1000
namespace speed
{
class testImpl
{
public:
testImpl( void ) : data( 0 ) {}
void clear( void ) { data = 0; }
void test1( void )
{
for( unsigned long long i = 0ULL; i < C; ++i )
{
++data;
}
}
inline void test2( void )
{
for( unsigned long long i = 0ULL; i < C; ++i )
{
++data;
}
}
int data;
};
class testClass
{
public:
testImpl *m_Impl;
public:
testClass( void )
{
m_Impl = new testImpl();
}
~testClass( void )
{
delete m_Impl;
}
void test1( void )
{
m_Impl->test1();
m_Impl->clear();
}
void test2( void )
{
m_Impl->test2();
m_Impl->clear();
}
void test3( void )
{
for( unsigned long long i = 0ULL; i < C; ++i )
{
++m_Impl->data;
}
m_Impl->clear();
}
};
static void test( void )
{
testClass aTest;
::timeBeginPeriod( 1 );
int t0 = ::timeGetTime();
aTest.test1();
int t1 = ::timeGetTime();
aTest.test2();
int t2 = ::timeGetTime();
aTest.test3();
int t3 = ::timeGetTime();
::timeEndPeriod( 1 );
std::printf( "time of normal/inline/expand : %d/%d/%d\r\n",t1-t0,t2-t1,t3-t2 );
std::printf( "value = %d",aTest.m_Impl->data );
}
};在我的机器上(AMD Althon XP 2200+ 512M)得到了以下平均值(多次输出,比较趋向中间值的结果):
debug : time of normal/inline/expand : 84/67/85
value = 0
release:time of normal/inline/expand : 36/16/19
value = 0