分享
 
 
 

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

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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评论:为vector和deque欢呼吧!十分的棒!。

来个总结吧。

比赛项目\参赛选手

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足够的空间,使用效率将成倍提高!另外,他们也并不是设计的一模一样,他们每一个都有自己独有的绝迹,如果能让他们充分发挥,你的程序想来也将上一个档次。让我们共同努力吧。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有