类库大魔王
类库大魔王 懒惰,傲慢,以及无耐心

Windows下编译器内存分配释放性能对比

  前些天有人在群里说起测试malloc和HeapAlloc的效率,后来又在豆瓣上有人讨论起大块内存的策略问题,于是我决心再稍微仔细地测试一下各个编译器在这方面的表现。
  首先,我选取了OpenWatcom 1.8、Digital Mars 8.51、Borland 5.5、MinGW GCC 4.4.0、MSVC 2008、Intel 11.0.061一共6种编译器,除了Intel C++,其他的编译器都可以在网上下载并免费使用。
  然后写了一个非常简单的小程序,分别对1字节,1000字节,1024字节,1M字节,10M字节和50M字节进行重复的分配和释放,前三种大小重复15000000次,后三种大小重复150000次。为什么前三种的重复次数是后三种的100倍呢?因为测试过程中我发现,后三种的耗时在某些编译器中太长了,等不及了!
  接着,使用所有这些编译器编译出4种不同CRT配置的可执行程序。分别是单线程静态链接,单线程动态链接,多线程静态链接和多线程动态链接。我都是使用bjam的默认参数编译的,其中Intel编译器不能生成单线程静态链接的可执行程序,但我想影响很小,也就不再追究。
  最后就是运行每个程序,我的机器配置是Thinkpad T43,1.86GHz的P4m,1.5G内存,Windows XP SP3。每种跑10次,计平均时间,可以得到一些有趣的结果。从不同的维度观察这些数据,可以得到不同的结论。
  先比较不同编译器间的差别。从实际上看,MinGW和Intel都是使用了msvcrt,只不过默认情况下MinGW使用的是6.0版本,Intel则使用当前安装的VC的最高版本的CRT库,我的机器上是9.0,所以总的说来这三者的差别应该不大。
  在1字节的大小时,Digital Mars表现平稳而出色都在2s出头,而VC、MinGW和Intel都超过3s,OpenWatcom跟VC类似,但在单线程静态链接时就爆发了,只需要1s出头,而Borland在单线程中都只用1s多。
  1000字节的测试基本与1字节的情况相同,但Digital Mars的耗时却飚升了近1倍!
  而1024字节时,VC、MinGW和Intel的耗时又比1000字节时多了近1倍,看来这1000和1024之间有个阀值影响msvcrt使用不同的分配策略。
  在1M、10M和50M字节的测试中,三个测试的数据差别不大,但与前三者的测试数据比较可以看出,OpenWatcom和DigitalMars的表现平稳,变化不大,但使用msvcrt的三者则耗时飚升,大约是前二者的400~500倍,是1024字节的200~250倍,这个差别比较大!
  总的说来,Borland C++只有在单线程,小块内存分配时的表现还不错,这在DOS时代是好的,但进入了Windows时代,程序开发纷纷往多线程,大内存占用的方向发展时,它几乎没有进步。Open Watcom是受分配内存块大小影响最小的,几乎没有变化,而且总体上它在各个横向比较中性能是最好的。Digital Mars略次于Open Watcom,但它在单线程或多线程,静态或动态链接中几乎没有差别,估计最终使用的是同一个CRT库。VC、MinGW和Intel的表现基本相同,除了单线程静态链接小块内存分配外,其他情况都略好于Borland C++,所以可以看到Intel编译器的优化是集中在指令流的调整上,而对内存这块是忽略了。
  另外,我同样用C++中的new和delete进行了测试,从数据上看,略慢于malloc和free,最差距很小很小,平常的应用中基本可以忽略。而且使用Windows的HeapAlloc则可以看到,该API的表现与msvcrt的malloc/new接近,在1000字节和1024字节间有一个阀值。
  详细测试用可执行程序与测试结果可以点击这里下载。

感觉本文不错,不妨小额鼓励我一下!
支付宝扫一扫

支付宝扫一扫

微信扫一扫

微信扫一扫

如果你看不到评论框,说明Disqus被墙了。