VC6.0、7.0和BCB6.0中STL的性能比较(4)-vector

类别:编程语言 点击:0 评论:0 推荐:

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