我测试了一下STL的性能,这里先给出结果,10月3号之前给出详细测试过程及源码。

陈硕 2001-10-02 06:23:55
我测试了一下STL的性能,这里先给出结果,10月3号之前给出详细测试过程及源码。
测试方法:实现相同功能的三个程序(一个C,两个C++),用三种编译器编译,得9个exe文件,测试执行的时间,多次执行取平均值(时间单位:秒):

Borland C++ Complier 5.5.1
C version : 0.3242
C++ using list : 5.595
C++ using deque : 5.563

Visual C++ 6.0 with Service Pack 5
C version : 0.3945
C++ using list : 1.889
C++ using deque : 137.x (两分多钟,太奇怪了)

GNU C++ 2.95.3 with Cygwin1.dll 1.3.2
C version : 0.3300
C++ using list : 1.700
C++ using deque : 2.582

目前有三点结论:
Borland C++ Complier 5.5.1的STL确实比较差劲
Visual C++ 6.0的deque有问题, 执行时机器传出硬盘狂响曲.
GNU C++ 2.95.3的比较“正常”,但比起设计良好的C程序,STL要慢一些。
由于GNU C++比较正常,可以推论list比deque快。
...全文
330 26 打赏 收藏 举报
写回复
26 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
陈硕 2001-10-07
假期结束了,唉,晚上给分!
  • 打赏
  • 举报
回复
陈硕 2001-10-06
我用hash_map试了一下,果然快很多,在GNU C++下由原来的1.70s变为0.83s(均使用list),请问"qqchen79(知秋一叶)"你的hash是怎么写的,

我用的是下面这个:
typedef list<string> Prefix;

template <class __Key> struct cshash{};

template <>
struct lshash<Prefix>
{
size_t operator()(const Prefix &pref) const {
unsigned int h = 0;
int i;
for (Prefix::const_iterator iter = pref.begin(); iter != pref.end(); ++iter) {
for(i = 0; i < (*iter).size(); ++i)
h = 5 * h + (*iter)[i];
}
return h;
}
};

hash_map<Prefix, vector<string>, lshash <Prefix > > statetab;
  • 打赏
  • 举报
回复
qqchen79 2001-10-06

同理,deque比list慢是因为它提供了随机存取的能力,但这种能力我们的程序中并不需要。所以,在这个程序中应该选用的是list而不是deque。
list版本改用hash_map的结果是0.29s,而且其它部分代码一字未改!大家不妨自己试一下。20%-30%的性能差异应该是可以接受的——这下大家对STL满意了吧!

这里想说明的一点是:不要试图计较STL中各个容器之间的性能差异(VC的deque除外),因为他们本身的用途就不同,比如:简单的顺序访问list也许比deque要快,但随即访问呢?我们更多考虑的应该是那种容器提供了恰如其分的你所需要的功能,不多不少,这样,一般情况下你也就选择了性能最优的容器。
  • 打赏
  • 举报
回复
say 2001-10-06
gz
  • 打赏
  • 举报
回复
qqchen79 2001-10-06
SGI STL缺省为const char*实现了hash,我只是用所有string.c_str的hash值异或。
因为C版本的hash函数用了乘法,所以我的要比它的快一点:), 也不用两重循环。
应该确定除了特殊情况以外,C++/STL比C慢一些(10-20%)基本上是正常的,但相对于程序的易维护性、可扩充性和简易性而言,这样的差异应该不是很大的问题。我觉得也不能一味的追求性能,性能只是适应需求就行了,另外,性能差一点的程序也能促进PC工业走出低谷嘛!

To Solstice(胖胖):
我的机器 > PIII866,不过是公司的 //sigh.
BTW:你也学的太认真了,深更半夜的写STL :),还得好好休息呀。
  • 打赏
  • 举报
回复
陈硕 2001-10-06
qqchen79(知秋一叶):
你用的是PIII 866以上吧?
  • 打赏
  • 举报
回复
陈硕 2001-10-06
在VC6 + SGI STL下,用以上程序,时间由原来的1.074s变为0.644秒(C版为0.459s, 比STL快28.7%)。
我仿造C版的思路用STL重写了一个markov.cpp(显得有点不伦不类,呵呵),时间为0.545s,C版仅比它快15.8%。这个速度已经相当令人满意了。

感谢myan与qqchen79(知秋一叶), 两位参与这次讨论使我学到了不少东西。

  • 打赏
  • 举报
回复
陈硕 2001-10-06
夜深人静,便于思考嘛,白天学校太吵闹了。反正是假期,可以白天睡觉,所以晚上学习学习也行。
  • 打赏
  • 举报
回复
qqchen79 2001-10-05
我刚刚仔细看了C与STL版本的程序,简直是误导啊!
在C的版本里,他用hash来实现prefix键值的查找,但在C++里,它选的容器居然是map!!
怎么说呢,这就好比用VB编了快速排序,然后用ASM编了冒泡,谁会快呢?
众所周知,map的功能不仅仅是提供快速的查找,而且是“有序的”快速查找,比hash表功能要强,直观上看,功能越多速度越慢应该算是常识;具体的复杂度分析,hash表的平均比较次数基本上是O(1)的,而map仍然需要O(logN)的比较,当比较的对象是string(用strcmp)甚至是deque<string>(多少次strcmp?)时,这种差异将会是致命的!
当然,还有一些其它的差异,比如说C中直接使用指针,而STL中直接使用string作为容器的对象,但这些都不是主要问题。
我尝试使用SGI STL的hash_map替代map,结果如下(我的机器比较快:) )
* 编译均使用/MT /GX /O2
C version: 0.22s
map version: 0.62s
hash_map version: 0.35s
当然,还可以有其他一些优化,比如用string*代替string,甚至建立string pool等等。都比较麻烦。这里的map -> hash_map很容易做,只需写一个hash函数就好了。我就不列出代码了。
  • 打赏
  • 举报
回复
陈硕 2001-10-05
myan():
我现在还是一个C++初学者,过一阵子“精细的设计核心结构”来重做这个测试,看看结果如何。
  • 打赏
  • 举报
回复
陈硕 2001-10-05
下面来搞点移花接木,把GNU C++带的STL给其他两个编译器用看看有什么效果。
在www.sgi.com下载了SGI STL 3.3,在下载时顺便看了看FAQ,得知SGI STL3.3与Visual C++5.0以上搭配时,需要用iostream.h取代iostream;还有是支持SGI STL的编译器里好像没有Borland C++。
把下载来的STL.ZIP释放到C:\Program Files\Microsoft Visual Studio\VC98\Include\SGISTL。并把环境变量重新设置:
set INCLUDE=C:\PROGRA~1\MICROS~3\VC98\INCLUDE\SGISTL;C:\PROGRA~1\MICROS~3\VC98\INCLUDE
然后把markov_l.cpp与markov_d.cpp中的#include<iostream>改为#include<iostream.h>
用cl /G6 /O2 /Og /GX /MT /Fev_d_sgi.exe markov_d.cpp 编译成功,这样又得到两个EXE文件:v_l_sgi.exe与v_d_sgi.exe,前者是markov_l.cpp编译生成的。下面是这两个EXE的平均执行时间:
PII 300 with 64M RAM PII 350 with 128M RAM
v_l_sgi 1.375 1.074
v_d_sgi 1.943 1.597
哇!比GNU C++本身还要快!当然这个简单的测试并不能证明SGI STL与VC6配合默契,有兴趣的朋友可以进一步测试。
但事情在Borland C++ 5.5.1上就没这么顺利了,我试了好多方法,但程序都不能用SGI STL。有兴趣的朋友可以去www.stlport.org下载STLport 4.5来和Borland C++ 5.5.1配合使用,看看性能如何。
  • 打赏
  • 举报
回复
陈硕 2001-10-05
嗯,编程还是要动脑子的。
  • 打赏
  • 举报
回复
myan 2001-10-05
STL是一套framework,本来就是希望大家能够利用其中的结构和工具进行扩展的,如果有了STL,就不再愿意自己设计数据结构了,岂不是适得其反。尽信书不如无书.
  • 打赏
  • 举报
回复
nasco 2001-10-04
老K的那程序我看过,挺无聊的,有点像这本书,不论不类。

世界上如果有使用效率和复杂度都占优的,别的同类也就可以见鬼去了。始终相信工程是在效率(效果?)和花费上找平衡点。

BTW:老k那书已经测试了那n种语言实现这个程序,老兄不觉得过瘾?
  • 打赏
  • 举报
回复
xwu 2001-10-04
To: Solstice(胖胖):
借用一下你的测试数据.谢谢. :0).
To: myan:
deque 是不常见, 但不幸的是, 我的项目要大量使用 deque :0(. 请看:
http://www.csdn.net/expert/TopicView.asp?id=311859

还有: 我对STL不太熟, 但我一直以为 map 就是 hash. 不知对吗?
  • 打赏
  • 举报
回复
tangtao 2001-10-04
to Solstice:
我觉得这个测试还有改进的余地。
你是不同的编译器配合不同版本的STL来做的测试,这样差异较大,究竟是编译器引起的还是STL引起的不得而知。建议再测一组数据,用不同的编译器来测试stlport4.5。这样结果可能更有说服力。
  • 打赏
  • 举报
回复
myan 2001-10-04
那个例子我早就做过类似的测试,我以为不足为证。因为文中使用的C数据结构是专门为这个马尔可夫算法量身定做的,而STL的例子使用了一个不太合适的模拟,而且使用了STL中效率最差的deque。deque效率差是因为其内部实现非常独特,其实deque是一个不常见的数据结构,它的存在一直让我很纳闷:连hash都没做,为什么做了这么一个奇怪的数据结构呢?

总之,Kernighan在这个例子中对STL的使用是比较随意的,而对于C的使用是非常精致的。如果使用STL来做这个程序,需要精细的设计核心结构。

另外,一个更重要的问题是,现在很多编译器还没有考虑到STL的大量应用,所以很多针对性的优化还没有放进编译器中。如果专门针对STL进行优化,减少不必要的临时对象和拷贝操作,结果会大大好转。我上次做测试的时候,手头上还有KAI C++ 4.0,当时的测试结果是,C程序0.22秒,KCC 0.48秒,单词数20000。差距并不很大。
  • 打赏
  • 举报
回复
陈硕 2001-10-04
因该说我在这里只测试了部分Container的性能(测试还未必严格),对Algorithms / Iterators 均未做测试.
我对使用STL的看法是:
1. 谁都知道设计良好的ASM程序比C快,但在做稍大一点的程序时谁会只用ASM ?
2. Kernighan有本事在他写的程序里只用C, 而且保持良好的效率与可维护性, 我没有这个本事.
3. STL至少给我们带来了巨大的方便, 使我们更加专注地关心所要解决的问题本身, 从程序的代码量上就能看出, 用STL的程序只有70行, 而C程序有160行.
所以我会毫不犹豫地在程序中使用STL .
  • 打赏
  • 举报
回复
陈硕 2001-10-03
测试全文已发布在(PDF格式):
http://263.csdn.net/FileBBS/files/2001_10/T_652_1.zip
测试用的源代码及数据文件在:
http://263.csdn.net/FileBBS/files/2001_10/T_652_2.zip

在我的主页也可以下载(文章一栏):
http://www.chenshuo.com
  • 打赏
  • 举报
回复
CNer 2001-10-03
哦,,,,我也瞧瞧。。。
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
申请成为版主
帖子事件
创建了帖子
2001-10-02 06:23
社区公告
暂无公告