woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较

这里比较的VC++编译的C++代码中的性能

我用的是VC6.0测试的

就不介绍这几个的用法了

我写了一段简单的测试代码

测试结果是:

malloc:390
new:391
VirtualAlloc:454
HeapAlloc:47

很明显的是HeapAlloc分配速度最快,malloc次之,newmalloc差不多,VirtualAlloc最慢了(以前小强跟我说这个最快)

我有跟踪了一下

new调用了这段代码

  1. void * __cdecl _nh_malloc (
  2.         size_t nSize,
  3.         int nhFlag
  4.          )
  5. {
  6.         return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL, 0);
  7. }

malloc函数是这样的:

  1. _CRTIMP void * __cdecl malloc (
  2.         size_t nSize
  3.          )
  4. {
  5.         return _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL, 0);
  6. }
  7.  

很明显,newmalloc最终调用相同的_nh_malloc_dbg,只是new多了一次函数调用

再继续跟下去,发现最终调用的是return HeapAlloc(_crtheap, 0, size);

基本上真相大白了

VirtualAlloc跟踪不进去,如果说分配的是虚拟内存的话,有可能会慢吧。

回头再认真看看《Windows核心编程》这本书!

欢迎指正!欢迎交流!

测试代码如下:

  1. /******************************************************************
  2. *
  3. * Copyright (c) 2008, xxxx
  4. * All rights reserved.
  5. *
  6. * 文件名称:main.cpp
  7. *     要: 测试申请内存的速度
  8. *
  9. * 当前版本:1.0
  10. *      者:吴会然
  11. * 完成日期:2008-11-30
  12. *
  13. * 取代版本:
  14. *    作者:
  15. * 完成日期:
  16. *
  17. ******************************************************************/
  18.  
  19. #include <iostream>
  20. #include <windows.h>
  21. using namespace std;
  22.  
  23. int main( int argc, char *argv[] )
  24. {
  25.     int i = 0;
  26.     DWORD dw1 = 0, dw2 = 0, dw3 = 0, dw4 = 0;
  27.     DWORD dwStart = 0;
  28.     DWORD dwEnd = 0;
  29.     for( int j = 0; j < 10; j++ )
  30.      {
  31.          dwStart = ::GetTickCount();
  32.         for( i = 0; i < 20000; i++ )
  33.          {
  34.             char *pDest1 = (char *)malloc(4096);
  35.              free( pDest1 );
  36.     
  37.          }
  38.          dwEnd = ::GetTickCount();
  39.          cout << "malloc 100004096大小的内存块,耗时" << dwEnd - dwStart << endl;
  40.          dw1 += dwEnd - dwStart;
  41.  
  42.          dwStart = ::GetTickCount();
  43.         for( i = 0; i < 20000; i++ )
  44.          {
  45.             char *pDest2 = new char[4096];
  46.             delete pDest2;
  47.     
  48.          }
  49.          dwEnd = ::GetTickCount();
  50.          cout << "new 100004096大小的内存块,耗时" << dwEnd - dwStart << endl;
  51.          dw2 += dwEnd - dwStart;
  52.  
  53.          dwStart = ::GetTickCount();
  54.         for( i = 0; i < 20000; i++ )
  55.          {
  56.             void* pMem = ::VirtualAlloc(NULL, 4096,   MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
  57.              ::VirtualFree(pMem, 0, MEM_RELEASE);
  58.          }
  59.          dwEnd = ::GetTickCount();
  60.          cout << "VirtualAlloc 100004096大小的内存块,耗时" << dwEnd - dwStart << endl;
  61.          dw3 += dwEnd - dwStart;
  62.  
  63.         HANDLE hHeap = ::HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
  64.          dwStart = ::GetTickCount();
  65.         for( i = 0; i < 20000; i++ )
  66.          {
  67.             void* pMem2 = ::HeapAlloc(hHeap, HEAP_NO_SERIALIZE, 4096 );
  68.              ::HeapFree(hHeap, HEAP_NO_SERIALIZE, pMem2);
  69.  
  70.          }
  71.          dwEnd = ::GetTickCount();
  72.          cout << "HeapAlloc 100004096大小的内存块,耗时" << dwEnd - dwStart << endl;
  73.          dw4 += dwEnd - dwStart;
  74.  
  75.      }
  76.  
  77.      cout << "malloc:" << dw1 << endl;
  78.      cout << "new:" << dw2 << endl;   
  79.      cout << "VirtualAlloc:" << dw3 << endl;   
  80.      cout << "HeapAlloc:" << dw4

 

 

 

====================================

转】李玮剑 评论
1 把分配的内存空间改为4M甚至更高(循环次数减少)试试,结果截然不同。处理M级的大文件时,用VirtualAlloc效率高

2 博主的测试需要考究,系统在创建线程时就已经预先在线程的堆栈段中提交了两个页面。 按照我的观点new和malloc只要消耗的内存没有超过页面大小就不会实际的进行存储器的保留与提交。二者的操作不在一个层面上。

3 在分配大于一个页面数据的时候 virtualAlloc才有意义

4 virtualAlloc是操作系统提供的最根本的内存分配接口。HeapAlloc预先使用virtualAlloc申请了大块的内存,并根据优化算法组织了用于内存管理的数据结构,主要是对小内存分配的优化 new和malloc是语言层面接口,由于HeapAlloc已经有了优化,所以vc中的malloc并没有使用更多的优化算法,直接转入 HeapAlloc。

posted on 2011-08-12 10:59 肥仔 阅读(15819) 评论(14)  编辑 收藏 引用 所属分类: Windows开发

评论

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

楼主我执行你的代码的结果是:
malloc 1840
new 1842
VirtualAlloc 311
HeapAlloc 1608
根本和你的不一样啊
是 VS2008 + win7的执行结果, 内存2G
2011-08-12 20:55 | Cunch

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

楼主的是错的 你在实际打印看看
2011-08-19 15:27 | asf

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较[未登录]  回复  更多评论   

如果我没有记错的话VirtualAlloc只能正页的分内存,在Win32上每页是4096字节,它是虚拟内存管理器对外的API。

其实像malloc,new ...这样的速度就不要拿出来晒了,慢还不说,多CPU场合并行时速度大大下降,因为普通的并发控制机制成为瓶颈。如果一定非要在单线程分配内存比速度,单块内存256KB以下时(大块没有优化),DLMalloc会轻松灭掉各种malloc,不论什么系统。

如果CPU个数超过8个,并行分配内存,jemalloc和Hoard可能是霸主,操作系统的API做的再好也得俯首称臣。jemalloc和Hoard谁快谁慢,我不清楚,相信相差无几。如果CPU个数6个以下,并行分配,ptmalloc3加速比也不错,且overhead很小。谷歌的CMalloc听说也不错,且能回收垃圾内存,只不过启动速度慢死,跟启动Java虚拟机绝对有一拼!
2011-08-19 22:08 | Chipset

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较[未登录]  回复  更多评论   

我的结果与以上两位趋势都不同。
malloc:47
new:63
VirtualAlloc:404
HeapAlloc:79

Win7中文版64位系统,g++4.6.1编译器64位(-O3),CPU AMD X4 910e, 2.6GHz,内存单条4GB DDR3 1333
2011-08-19 22:48 | Chipset

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较[未登录]  回复  更多评论   

数据量相同情况下,测试了一下DLMalloc版本2.8.5,结果为:
DLMAlloc:16

可见DLMalloc还是比较快的。

数据量加大10倍,相对误差能小一点,但趋势不变。

malloc:332
new:551
VirtualAlloc:3124
HeapAlloc:845
DLMalloc:62
2011-08-19 23:10 | Chipset

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

非常不错的文章
2011-12-02 20:53 | 美利坚

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

我的执行结果比较诡异:
第一遍
malloc:172
new:170
VirtualAlloc:220
HeapAlloc:61
第二遍
malloc:157
new:173
VirtualAlloc:203
HeapAlloc:32
第三遍
malloc:217
new:158
VirtualAlloc:201
HeapAlloc:0
第四遍
malloc:203
new:206
VirtualAlloc:217
HeapAlloc:30
我的配置是vs2008+win7 x64,6g
2012-01-01 17:37 | swordzj

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

你们用这种方法测试,都忽略了一个严重的问题,那就是 WINDOWS是【多任务抢占式操作系统】,意味着 你们的结果根本不具有考究性,,如果在DOS机上测试还可以
2012-03-16 09:17 | noi

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

楼主居然测试debug版本的速度!!!
2012-06-22 15:10 | 徐大侠

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

分配大内存的时候 VirtualAlloc才能体现出优势,至于小块内存那就是HeapAlloc, malloc和new都是调用HeapAlloc,这就不用比较了。楼主可以尝试分配个几兆的内存,VirtualAlloc就会凸显其速度,越大效率就越高。
2012-09-15 13:02 | suhetao

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

这些函数没得比较的,malloc比new快倒是,VirtualAlloc如果只分配地址而不分配实际内存的话,比什么都快,.而C运行时库会优化过,启动代码有可能自己申请一块内存,然后小内存分配就在这个内存中分配,而不通过系统函数,,,比较其实没什么意义
2013-06-06 08:50 | 喵喵

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

我的测试结果如下,发现与申请的内存块大小有很大关系。

测试1:100000次518000大小
#=== round 1 ======#
malloc 100000次518000大小的内存块,耗时952
new 100000次518000大小的内存块,耗时921
VirtualAlloc 100000次518000大小的内存块,耗时156
HeapAlloc 100000次518000大小的内存块,耗时936
#=== round 2 ======#
malloc 100000次518000大小的内存块,耗时874
new 100000次518000大小的内存块,耗时796
VirtualAlloc 100000次518000大小的内存块,耗时156
HeapAlloc 100000次518000大小的内存块,耗时858
#=== round 3 ======#
malloc 100000次518000大小的内存块,耗时936
new 100000次518000大小的内存块,耗时920
VirtualAlloc 100000次518000大小的内存块,耗时156
HeapAlloc 100000次518000大小的内存块,耗时905


测试2:100000次516500大小
#=== round 1 ======#
malloc 100000次516500大小的内存块,耗时983
new 100000次516500大小的内存块,耗时1014
VirtualAlloc 100000次516500大小的内存块,耗时171
HeapAlloc 100000次516500大小的内存块,耗时936
#=== round 2 ======#
malloc 100000次516500大小的内存块,耗时952
new 100000次516500大小的内存块,耗时983
VirtualAlloc 100000次516500大小的内存块,耗时171
HeapAlloc 100000次516500大小的内存块,耗时951
#=== round 3 ======#
malloc 100000次516500大小的内存块,耗时920
new 100000次516500大小的内存块,耗时967
VirtualAlloc 100000次516500大小的内存块,耗时172
HeapAlloc 100000次516500大小的内存块,耗时967


测试3:100000次516000大小
#=== round 1 ======#
malloc 100000次516000大小的内存块,耗时47
new 100000次516000大小的内存块,耗时31
VirtualAlloc 100000次516000大小的内存块,耗时156
HeapAlloc 100000次516000大小的内存块,耗时16
#=== round 2 ======#
malloc 100000次516000大小的内存块,耗时31
new 100000次516000大小的内存块,耗时47
VirtualAlloc 100000次516000大小的内存块,耗时156
HeapAlloc 100000次516000大小的内存块,耗时32
#=== round 3 ======#
malloc 100000次516000大小的内存块,耗时47
new 100000次516000大小的内存块,耗时47
VirtualAlloc 100000次516000大小的内存块,耗时156
HeapAlloc 100000次516000大小的内存块,耗时31
2013-10-08 12:45 | kylixs

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

首先他们的应用场景不同
new和malloc都是语言级的封装,new和malloc本身又不同,主要是是否构造的不同

真正分配内存,都是heapAlloc或者virtualAlloc这样的系统API
而new和malloc都是最终调用heapAlloc,从系统默认堆上分配内存,如果内存不足,可以调用heapCreate来创建新的堆

virtualAlloc一般用于大的内存分配,而且virtualAlloc更加底层,涉及虚拟内存,经过保留和提交物理存储器等过程。

看看这个
http://www.seanyxie.com/mallocnewheapallocvirtualalloc/
2014-09-20 21:11 | xie

# re: malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较  回复  更多评论   

new 或 malloc调用heapalloc,heapalloc调用virtualalloc。底层速度更快。
如果你显示的结果慢,那是因为你使用方式不符合相对应的API特点而已。
2015-04-12 15:36 | 看到了

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理