前几天在tctop中看到JULY整理的Google迷你版编程规范,有一点看后觉得实在是非常受用,为此特意写了一个程序来进一步说明。
代码如下:
#include <boost/timer.hpp>
#include <iostream>
using namespace boost;
using namespace std;
class A{
public:
A(int data = 1){
ptr = new int;
*ptr = data;
}
void foo(){ptr = 0;}
~A(){delete ptr;}
int GetData(){
return *ptr;
}
private:
int *ptr;
};
int main(){
timer t;
cout << "call A before loop:" << endl;
A a;
for(int i = 0; i < 10000000; ++i)
a.foo();
cout << t.elapsed() << endl;
t.restart();
cout << "call A during loop:" << endl;
for(int i = 0; i < 10000000; ++i){
A b;
b.foo();
}
cout << t.elapsed() << endl;
}
先看运行结果:
call A before loop:
0.109
call A during loop:
2.281
两者的运行时间相差22倍。
A a;定义在fo循环之外,只需要执行一次构造函数和析构函数。循环体执行1000万次foo()成员函数,作用是让数据成员ptr置空。
而A b;定义在for循环之内,总共执行1000万次构造函数和析构函数,当然还有foo()成员函数,作用一样,风格不一样,运行时间的差距可见一斑。
再看一例:
#include <iostream>
using namespace std;
class A{
bool a;
int b;
bool c;
};
class AA{
bool a;
bool b;
int c;
};
int main(){
cout << sizeof(A) << endl
<< sizeof(AA) << endl;
}
运行结果:
12
8
为什么是这样呢?C++对象布局是以4的整数倍存储的,这样做是为了提高读取效率,不清楚的可以google一下“字节对齐”。
A的布局如下:
| bool a | int b | bool c|
1 4 1
B的布局如下:
| bool a | bool b | int c |
1 1 4
由于字节对齐,编译器会自动为A类的a和c分别补上3个字节,这样就白白浪费了6个字节。
再看B类,由于a,b都只占1个字节,两者合在一起小于4,于是只需要补齐2个字节即可,加上int一共才8个字节。
所以说好的编程风格不仅能加速程序运行的速度,也能在内存方面插上一手以减小开销。