vector测试结果
说明:
本次测试包括vc6、vc7、BCB6.0的结果.VC7是新加进来的.
编译选项:
bcc32 main.cpp
cl /GX /Ob2 main.cpp
测试环境在这里:http://www.csdn.net/develop/article/18/18359.shtm
测试结果是20次最好结果的集合。
测试项目清单:
end : 循环调用1个size为20000的vector的end方法10000次
end c : 循环调用1个size为20000的vector的end(const)方法10000次
begin : 循环调用1个size为20000的vector的begin方法10000次
begin c : 循环调用1个size为20000的vector的begin(const)方法10000次
rend : 循环调用1个size为20000的vector的rend方法10000次
rend c : 循环调用1个size为20000的vector的rend(const)方法10000次
rbegin : 循环调用1个size为20000的vector的rbegin方法10000次
rbegin c : 循环调用1个size为20000的vector的rbegin(const)方法10000次
at : 循环调用1个size为20000的vector的at(i)方法10000次,i=0~10000
at c : 循环调用1个size为20000的vector的at(i)const方法10000次,i=0~10000
[] : 循环调用1个size为20000的vector的operator[](i)方法10000次,i=0~10000
[] c : 循环调用1个size为20000的vector的operator[]const方法10000次,i=0~10000
resize : 循环调用vector的resize(i)方法10000次,i=0~10000
resize d : 循环调用vector的resize(i)方法10000次,i=10000~0
front : 循环调用size为20000的vector的front方法10000次
front c : 循环调用size为20000的vector的front(const)方法10000次
back : 循环调用size为20000的vector的back方法10000次
back c : 循环调用size为20000的vector的back(const)方法10000次
push_back: 循环调用vector的push_back(i)方法10000次,i=0~10000
pop_back : 循环调用vector(开始size()=20000)的pop_back()方法10000次
assign1 : 大小为0的vector调用assign(const_iterator first, const_iterator last)方法1次,
复制10000个元素
assign2 : 同assign1,但是目标容器的初始大小是10000
assign3 : 大小为0的vector调用assign(size_type n, const T& x = T())方法1次,n=10000
assign4 : 大小为0的vector调用assign(size_type n, const T& x = T())方法10000次,n=1
assign5 : 大小为10000的vector调用assign(size_type n, const T& x = T())方法1次,n=10000
assign6 : 大小为10000的vector调用assign(size_type n, const T& x = T())方法10000次,n=1
= : operator=(),源容器大小为10000
insert1 : insert(iterator it, const T& x = T())。细节参见说明
insert2 : insert(iterator it, size_type n, const T& x),n=1。细节参见说明
insert3 : insert(iterator it, const_iterator first, const_iterator last)。细节参见说明
insert4 : insert(iterator it, const_iterator first, const_iterator last)。细节参见说明
erase1 : erase(iterator it),细节参见说明
erase2 : erase(iterator first, iterator last),细节参见说明
clear : clear一个size为10000的容器1次
swap : swap,10000次。一个容器的大小为10000,一个大小为0
++itr : ++iterator,10000次循环
--itr : --iterator,10000次循环
++r_itr : ++reverse_iterator,10000次循环
--r_itr : --reverse_iterator,10000次循环
++int : ++int,整型变量,对照iterator。10000次循环
*itr : *iterator,10000次循环
*r_itr : *reverse_iterator,10000次循环
VC6的结果:
title end end c begin begin c rend
tickts 47296 46792 47248 46792 104744
ms 2.5946e-002 2.5670e-002 2.5920e-002 2.5670e-002 5.7461e-002
title rend c rbegin rbegin c at at c
tickts not support 104672 not support 287504 286940
ms 5.7422e-002 1.5772e-001 1.5741e-001
title [] [] c resize resize d front
tickts 80568 80156 1252804 969452 94288
ms 4.4199e-002 4.3973e-002 6.8727e-001 5.3183e-001 5.1725e-002
title front c back back c push_back pop_back
tickts 70156 92312 90176 1529248 420860
ms 3.8487e-002 5.0641e-002 4.9470e-002 8.3893e-001 2.3088e-001
title assign1 assign2 assign3 assign4 assign5
tickts 205008 188932 462980 963308 346448
ms 1.1247e-001 1.0365e-001 2.5399e-001 5.2846e-001 1.9006e-001
title assign6 = insert1 insert2 insert3
tickts 927176 106320 548168228 547497952 2780461536
ms 5.0864e-001 5.8326e-002 3.0072e+002 3.0035e+002 1.5253e+003
title insert4 erase1 erase2 clear swap
tickts 1230320 822559528 61004 61016 1162232
ms 6.7494e-001 4.5125e+002 3.3466e-002 3.3473e-002 6.3759e-001
title ++itr --itr ++r_itr --r_itr ++int
tickts 80212 80212 187172 187172 43160
ms 4.4003e-002 4.4003e-002 1.0268e-001 1.0268e-001 2.3677e-002
title *itr *r_itr
tickts 57364 57256
ms 3.1469e-002 3.1410e-002
VC7的结果:
title end end c begin begin c rend
tickts 104712 139000 104408 139112 157720
ms 5.7603e-002 7.6465e-002 5.7436e-002 7.6527e-002 8.6763e-002
title rend c rbegin rbegin c at at c
tickts 258560 158032 258184 325064 323864
ms 1.4224e-001 8.6935e-002 1.4203e-001 1.7882e-001 1.7816e-001
title [] [] c resize resize d front
tickts 159932 159524 6332484 2249696 104904
ms 8.7980e-002 8.7755e-002 3.4835e+000 1.2376e+000 5.7708e-002
title front c back back c push_back pop_back
tickts 104300 175908 173060 2742160 539092
ms 5.7376e-002 9.6768e-002 9.5202e-002 1.5085e+000 2.9656e-001
title assign1 assign2 assign3 assign4 assign5
tickts 484576 481272 257340 6417528 344204
ms 2.6657e-001 2.6475e-001 1.4156e-001 3.5303e+000 1.8935e-001
title assign6 = insert1 insert2 insert3
tickts 6553384 311524 980503540 994806540 5058278604
ms 3.6051e+000 1.7137e-001 5.3938e+002 5.4725e+002 2.7826e+003
title insert4 erase1 erase2 clear swap
tickts 1576900 2328091024 62076 49904 984524
ms 8.6746e-001 1.2807e+003 3.4148e-002 2.7453e-002 5.4159e-001
title ++itr --itr ++r_itr --r_itr ++int
tickts 90444 88884 88896 88900 42776
ms 4.9754e-002 4.8896e-002 4.8902e-002 4.8905e-002 2.3531e-002
title *itr *r_itr
tickts 57040 57168
ms 3.1378e-002 3.1449e-002
BCB6.0的结果:
title end end c begin begin c rend
tickts 22064 15568 15588 15548 40212
ms 1.2138e-02 8.5641e-03 8.5751e-03 8.5531e-03 2.2121e-02
title rend c rbegin rbegin c at at c
tickts 40208 40240 40464 60600 60640
ms 2.2119e-02 2.2136e-02 2.2260e-02 3.3337e-02 3.3359e-02
title [] [] c resize resize d front
tickts 20264 20240 1693360 376272 15524
ms 1.1147e-02 1.1134e-02 9.3153e-01 2.0699e-01 8.5399e-03
title front c back back c push_back pop_back
tickts 40564 40596 15268 194368 30236
ms 2.2315e-02 2.2332e-02 8.3990e-03 1.0692e-01 1.6633e-02
title assign1 assign2 assign3 assign4 assign5
tickts 49524 53668 44204 1120868 30308
ms 2.7244e-02 2.9523e-02 2.4317e-02 6.1660e-01 1.6673e-02
title assign6 = insert1 insert2 insert3
tickts 1171784 61804 84884860 84595868 428456320
ms 6.4461e-01 3.3999e-02 4.6696e+01 4.6537e+01 2.3570e+02
title insert4 erase1 erase2 clear swap
tickts 190840 247971700 180 172 155468
ms 1.0498e-01 1.3641e+02 9.9019e-05 9.4619e-05 8.5524e-02
title ++itr --itr ++r_itr --r_itr ++int
tickts 30236 30220 30208 30216 20228
ms 1.6633e-02 1.6624e-02 1.6618e-02 1.6622e-02 1.1128e-02
title *itr *r_itr
tickts 15232 15236
ms 8.3792e-03 8.3814e-03
测试结果分析:
我做这个比较的目的是出于对STL的一个理解和学习,尽管我无意挑起编译器的争端,但是事实却非如此。我既然开了这个争端的头,好也罢,坏也罢,总要
有头有尾,大家爱怎么说怎么说去吧。
性能差别很明显,BCB6.0又是胜出者。不知道是不是我的编译选项的问题,VC7的编译结果速度上不如VC6。尽管如此,我还是认为VC7编译器比VC6好,VC6的
兼容性问题多一些。这次加入VC7,是因为有人认为这种比较太不公平,我以为是暗示VC7会快一些,但结果并非如此.
带C后缀的测试项目是表示const的方法,我一直认为const的方法应该至少不会比非const的慢,大多数情况确实如此,但是也有例外,VC7的rend和rbegin,BCB
的front尤为突出。从软件的角度出发,我建议尽可能的用const约束。另外,VC6没有实现rbegin和rend的const方法。
end的效率非常重要,我们常常用它来作是否结束循环的判断。
在最求性能的地方,at和[]的差距也不小,但是他们调用频率很高,我个人倾向于用断言+[]取代at。
resize和resize d测试的区别在于resize是从小容量一直往上增长,后者则是缩减容量。相对来说内存分配的开销是比较大的,但是VC6中两者差别并不是非
常大,而在VC7和BCB中则差别巨大。
push_back的效率还是很高的,对比内存操作测试的结果就能看出:平均每个操作的时间小于内存分配操作的时间。
assign1和assign2的比较只是再次强调了vector内存重分配相对来说是个高代价的操作。assign2避免了内存重分配。assign和赋值操作比起来,赋值操作快
。虽然差距不小,但是没有预想中的差别大。
insert1的测试主要代码如下:
for (int i = 0; i < LOOPCOUNT; i++,i++,++itr)
{
itr = vec.insert(itr,T(i));
itr = vec.insert(itr,T(i));
}
这么做的目的是为了让移动元素的个数接近统计上的平均值,插入的元素个数是20000个。insert2~3也采用了同样的技巧。insert3中的from和to区间只有一个元
素。insert4的测试主要代码如下:
cont.insert(cont.begin(), vec.begin(), vec.end());
vec的大小是10000。
erase1的主要测试代码:
for (int i = 0; i < LOOPCOUNT; i++,i++)
{
vec.erase(vec.begin());
vec.erase(vec.end() - 1);
}
erase2的测试代码:
vec.erase(vec.begin(), vec.end());
通过insert和erase的结果来看,插入删除操作多的时候,早早的考虑别的容器吧,比如list。
迭代器是高性能的,它超过了[]操作。我建议,应该尽可能的使用迭代器,让C的影响力和STL保持距离,iterator确实可以做任何[]能做的事情.
本文地址:http://com.8s8s.com/it/it29242.htm