这几天在编写大运算量的程序时,发现vector和list用iterator来访问时速度奇慢,后来查了相关资料才知道在debug在确实是这样,而在release下速度还是很快的。
可以参考一下一篇文章:
debug模式下:
先不看case3,因为BOOST_FOREACH的效率在debug模式下与其它相差较大。Case4也不看
case1与case2的效率基本相同。
注意case1中的主要操作是*和++;而case2中主要是[]和size(),特别的,size()还可以改STL原码除去,这样case2将大为缩短时间。
而在Release模式下,case2比case1略优:
通过跟踪可以发现:
vector的size()函数里使用了一个三元操作符?:,而不是直接返回size,但这里没有安全检查。
operator*()与++()中,即便在release版本中,都会包含指针检查(ASM中的__imp___invalid_parameter_noinfo部分),每个操作都包括_SCL_SECURE_VALIDATE及_SCL_SECURE_VALIDATE_RANGE,但这些消耗的时间不多。两个检查若没通过都会转到__imp___invalid_parameter_noinfo中。
struct case1 {
int operator() (const vector<int> & v, size_t size) {
int sum=0;
vector<int>::const_iterator it = v.begin(); // 一个检查
for (size_t i=0; i< size; ++i, ++it ) { // 一个检查
sum += *it; // 一个检查
}
return sum;
}};
struct case2 {
int operator() (const vector<int> & v, size_t size) {
int sum=0;
for(size_t i=0; i< size; ++i) {
sum += v[i];//一个检查,但是包含求size()的检查
}
return sum;
}};
在[]操作中,包括一个_SCL_SECURE_VALIDATE_RANGE(_Pos < size()),而求size()费时。
Case4中包含更多的安全检查。
要消除这些安全查检,可以定义_SECURE_SCL为0。
消除检查之后,得到如下结果。两种方式的效率已经相当接近,但case1还是略优。改写后的Case3和4也与前两者接近。
剩下的只能用vtune来分析每个操作了。
结论:不论用哪种方法,release版的效率都差不多。
1. 少使用size()。
2. 使用[]访问,使调试与发布的运行效率接近。