C++ 常用模板武道会 第一场:vector v.s. list v.s. deque(下)

原创 2001年07月04日 17:11:00

C++ 常用模板武道会 第一场:

vector v.s. list v.s. deque

原创作者:beyond_ml

 

为了节省时间和空间,下面这个程序将系统测试后面的所有项目。然后根据具体的结果分析各个参赛选手的性能差异。

SequencePerformance.cpp

//: C04:SequencePerformance.cpp

// Comparing the performance of the basic

// sequence containers for various operations

#include <vector>

#include <queue>

#include <list>

#include <iostream>

#include <string>

#include <typeinfo>

#include <ctime>

#include <cstdlib>

using namespace std;

class FixedSize

{

int x[20];

// Automatic generation of default constructor,

// copy-constructor and operator=

} fs;

 

template<class Cont>

struct InsertBack

{

       void operator()(Cont& c, long count)

       {

              for(long i = 0; i < count; i++)

              c.push_back(fs);

       }

       char* testName() { return "InsertBack"; }

};

 

template<class Cont>

struct InsertFront

{

       void operator()(Cont& c, long count)

       {

              long cnt = count * 10;

              for(long i = 0; i < cnt; i++)

              c.push_front(fs);

       }

       char* testName() { return "InsertFront"; }

};

 

template<class Cont>

struct InsertMiddle

{

       void operator()(Cont& c, long count)

       {

              typename Cont::iterator it;

              long cnt = count / 10;

              for(long i = 0; i < cnt; i++)

              {

                     // Must get the iterator every time to keep

                     // from causing an access violation with

                     // vector. Increment it to put it in the

                     // middle of the container:

                     it = c.begin();

                     it++;

                     c.insert(it, fs);

              }

       }

       char* testName() { return "InsertMiddle"; }

};

 

template<class Cont>

struct RandomAccess

{ // Not for list

       void operator()(Cont& c, long count)

       {

              int sz = c.size();

              long cnt = count * 100;

              for(long i = 0; i < cnt; i++)

              c[rand() % sz];

       }

       char* testName() { return "RandomAccess"; }

};

 

template<class Cont>

struct Traversal

{

       void operator()(Cont& c, long count)

       {

              long cnt = count / 100;

              for(long i = 0; i < cnt; i++)

              {

                     typename Cont::iterator it = c.begin(),

                     end = c.end();

                     while(it != end) it++;

              }

       }

       char* testName() { return "Traversal"; }

};

 

template<class Cont>

struct Swap

{

       void operator()(Cont& c, long count)

       {

              int middle = c.size() / 2;

              typename Cont::iterator it = c.begin(),

              mid = c.begin();

              it++; // Put it in the middle

              for(int x = 0; x < middle + 1; x++)

              mid++;

              long cnt = count * 10;

              for(long i = 0; i < cnt; i++)

              swap(*it, *mid);

       }

       char* testName() { return "Swap"; }

};

 

template<class Cont>

struct RemoveMiddle

{

       void operator()(Cont& c, long count)

       {

              long cnt = count / 10;

              if(cnt > c.size())

              {

                     cout << "RemoveMiddle: not enough elements"

                     << endl;

                     return;

              }

              for(long i = 0; i < cnt; i++)

              {

                     typename Cont::iterator it = c.begin();

                     it++;

                     c.erase(it);

              }

       }

       char* testName() { return "RemoveMiddle"; }

};

 

template<class Cont>

struct RemoveBack

{

       void operator()(Cont& c, long count)

       {

              long cnt = count * 10;

              if(cnt > c.size())

              {

                     cout << "RemoveBack: not enough elements"

                     << endl;

                     return;

              }

              for(long i = 0; i < cnt; i++)

              c.pop_back();

       }

       char* testName() { return "RemoveBack"; }

};

 

template<class Op, class Container>

void measureTime(Op f, Container& c, long count)

{

       string id(typeid(f).name());

       bool Deque = id.find("deque") != string::npos;

       bool List = id.find("list") != string::npos;

       bool Vector = id.find("vector") !=string::npos;

       string cont = Deque ? "deque" : List ? "list"

       : Vector? "vector" : "unknown";

       cout << f.testName() << " for " << cont << ": ";

       // Standard C library CPU ticks:

       clock_t ticks = clock();

       f(c, count); // Run the test

       ticks = clock() - ticks;

       cout << ticks << endl;

}      

 

typedef deque<FixedSize> DF;

typedef list<FixedSize> LF;

typedef vector<FixedSize> VF;

 

int main(int argc, char* argv[])

{

       srand(time(0));

       long count = 1000;

      if(argc >= 2) count = atoi(argv[1]);

       DF deq;

       LF lst;

       VF vec, vecres;

       vecres.reserve(count); // Preallocate storage

       measureTime(InsertBack<VF>(), vec, count);

       measureTime(InsertBack<VF>(), vecres, count);

       measureTime(InsertBack<DF>(), deq, count);

       measureTime(InsertBack<LF>(), lst, count);

       // Can't push_front() with a vector:

       //! measureTime(InsertFront<VF>(), vec, count);

       measureTime(InsertFront<DF>(), deq, count);

       measureTime(InsertFront<LF>(), lst, count);

       measureTime(InsertMiddle<VF>(), vec, count);

       measureTime(InsertMiddle<DF>(), deq, count);

       measureTime(InsertMiddle<LF>(), lst, count);

       measureTime(RandomAccess<VF>(), vec, count);

       measureTime(RandomAccess<DF>(), deq, count);

       // Can't operator[] with a list:

       //! measureTime(RandomAccess<LF>(), lst, count);

       measureTime(Traversal<VF>(), vec, count);

       measureTime(Traversal<DF>(), deq, count);

       measureTime(Traversal<LF>(), lst, count);

       measureTime(Swap<VF>(), vec, count);

       measureTime(Swap<DF>(), deq, count);

       measureTime(Swap<LF>(), lst, count);

       measureTime(RemoveMiddle<VF>(), vec, count);

       measureTime(RemoveMiddle<DF>(), deq, count);

       measureTime(RemoveMiddle<LF>(), lst, count);

       vec.resize(vec.size() * 10); // Make it bigger

       measureTime(RemoveBack<VF>(), vec, count);

       measureTime(RemoveBack<DF>(), deq, count);

       measureTime(RemoveBack<LF>(), lst, count);

} ///:~

第四局 向前插入

 

vector弃权。他不支持push_front操作。

测试结果:

InsertFront for deque: 20000

InsertFront for list: 30000

Deque获胜。

Beyond_ml评论:毫不意外,deque的看家本领当然了得。

 

第五局 中间插入

测试结果:

InsertMiddle for vector: 40000

InsertMiddle for deque: 0

InsertMiddle for list: 0

Beyond_ml评论:难为vector了,在任何情况下,vector都不适合中间插入。同时我要为deque唱一把赞歌,能和list打成平手,实在了不起。

 

第六局 交换数据

测试结果:

Swap for vector: 0

Swap for deque: 10000

Swap for list: 20000

Beyond_ml评论:vector的集群优势非常适合作内存交换。

 

第七局 中间删除

测试结果:

RemoveMiddle for vector: 50000

RemoveMiddle for deque: 0

RemoveMiddle for list: 0

Beyond_ml评论:再次难为vector了,在任何情况下,vector同样不适合中间删除。同时我要再为deque唱一把赞歌,又list打成平手,实在了不起。

 

第八局 后部删除

测试结果:

RemoveBack for vector: 0

RemoveBack for deque: 0

RemoveBack for list: 20000

Beyond_ml评论:为vectordeque欢呼吧!十分的棒!。

 

来个总结吧。

比赛项目/参赛选手

Vector

Deque

List

内存管理

Poor

Good

perfect

使用[ ]at() 操作访问数据

Very good

Normal

N/A

Iterator的访问速度

Good

Very good

Good

Push_back操作(后插入)

Good

Good

Good

Push_front操作(前插入)

N/A

Very good

Good

Insert(中间插入)

Poor

Perfect

Perfect

Erase(中间删除)

Poor

Perfect

Perfect

Pop_back(后部删除)

Perfect

Perfect

Normal

Swap(交换数据)

Perfect

Very good

Good

遍历

Perfect

Good

Normal

 

哦,好像结束了,其实没有,我们还有很多事可以作!例如在使用vector的时候,我们能预先reserve足够的空间,使用效率将成倍提高!另外,他们也并不是设计的一模一样,他们每一个都有自己独有的绝迹,如果能让他们充分发挥,你的程序想来也将上一个档次。让我们共同努力吧。

STL中vector、list、deque的区别

1 vector     向量 相当于一个数组     在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即...
  • luliyuan
  • luliyuan
  • 2014年04月02日 11:12
  • 2088

STL中list,vector,deque,map,set区别、联系和使用场景原理

一、Vector:动态数组       vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随机存取,即[]操作符,但由于它的内存空间是连...
  • caojunhao123
  • caojunhao123
  • 2013年09月22日 20:35
  • 2025

C++三种容器:list、vector和deque的区别

在写C++程序的时候会发现STL是一个不错的东西,减少了代码量,使代码的复用率大大提高,减轻了程序猿的负担。还有一个就是容器,你会发现要是自己写一个链表、队列,或者是数组的时候,既要花时间还要操心怎么...
  • gogoky
  • gogoky
  • 2016年05月06日 17:35
  • 9424

c++的STL模板库中3种容器类:vector,list,deque的比较

c++的STL模板库中提供了3种容器类:vector,list,deque 对于这三种容器,在觉得好用的同时,经常会让我们困惑应该选择哪一种来实现我们的逻辑。 在少量数据操作的程序中随便哪一种用起来感...
  • panda1234lee
  • panda1234lee
  • 2013年03月01日 12:53
  • 956

JSP表格模板升级(2)-- 动态加载v.s.自定义标签初始化表格

前文《用JSP创建一个表格模板》中,我们已经创建了一个基本的jsp表格模板。这个模板究竟如何使用呢?本文介绍一下笔者用到的两种方式:调用Ajax动态更新页面,或用自定义标签来初始化。 调用Ajax动态...
  • NearEast
  • NearEast
  • 2013年11月30日 08:36
  • 3695

STL 笔记(一) 顺序容器 vector、list、deque常用函数

转载:http://blog.csdn.net/thisinnocence/article/details/39579647 STL 容器类 C++ STL 体现了泛型编程的思想,...
  • hlsdbd1990
  • hlsdbd1990
  • 2015年06月27日 22:27
  • 429

C++三种容器:list、vector和deque的区别

转载自:http://blog.csdn.net/gogokongyin/article/details/51178378 在写C++程序的时候会发现STL是一个不错的东西,减少了代码量,使代码...
  • Rasin_Wu
  • Rasin_Wu
  • 2018年01月11日 23:09
  • 6

c++容器(vector、list、deque)

http://apps.hi.baidu.com/share/detail/3279594 vector ,deque 和 list 顺序性容器: 向量 vector :   是一个线性顺...
  • xfortius
  • xfortius
  • 2012年07月18日 19:22
  • 7349

C++各个容器比较(vector,deque,list,set,map,queue,stack)

1、vector(连续的空间存储,可以使用[ ]操作符)可以快速的访问随机的元素,快速的在末尾插入元素,但是在序列中间随机的插入、删除元素要慢。而且,如果一开始分配的空间不够时,有一个重新分配更大空间...
  • xyb890826
  • xyb890826
  • 2014年09月07日 17:32
  • 487

c++标准库顺序容器vector,deque,list

顺序容器 Vector deque List 内存形式 类似加强版的队列 分配一块连续的内存,元素被顺序存储。当数值内存不够时,vector...
  • u014737238
  • u014737238
  • 2014年10月31日 16:00
  • 259
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 常用模板武道会 第一场:vector v.s. list v.s. deque(下)
举报原因:
原因补充:

(最多只允许输入30个字)