在win32上循环realloc

时间:2013-11-21 09:57:50

标签: macos winapi

C上的简单代码在内存中创建10 000 000数字 在Mac OS X上工作= 1秒
在Win32 Visual C ++ 2008上工作= 15分钟

在Mac和Win32 2Gb内存上

问:为什么?在Mac OS X上,Win32上的realloc工作得很慢?

// datrw.cpp : Defines the entry point for the console application.
//
#include "stdafx.h" // add for MSVC  
#include <stdio.h>    
#include <stdlib.h>
#include <malloc.h> // // add for MSVC
#define POOL   9030000000
#define ARSIZE   10000000
//int main() // for Mac OS X compile as :  gcc datrw.c 
int _tmain(int argc, _TCHAR* argv[]) // add for MSVC
{
double *data,*temp;
//----------------------------------------create data
data=(double *)malloc(sizeof(double)); // add (double *) for MSVC
double c; // data for save
int i;    // cycle variable
for(i=0;i<ARSIZE;i++){
  c=POOL+i;
  data[i]=c;
  temp=(double *)realloc(data,(i+2)*sizeof(double)); // add (double *) for MSVC
  if ( temp != NULL ) {
    data=temp;
  } else {
    free(data);
    printf("Error allocating memory!\n");
    return 1;
  }
}
return 0;
}

如果替换为:

for(i=0;i<ARSIZE;i++){
  c=POOL+i;
  //data[i]=c;
  temp=(double *)realloc(data,(i+2)*sizeof(double)); // (double *) MSVC
  if ( temp != NULL ) {
     data=temp;
     if ( temp == data ){ // add for optimize compilation
        data[i]=c;
     }
   } else {
     free(data);
       printf("Error allocating memory!\n");
      return 1;
  }
}

- 没有结果: - (

- 如果从FOR:

删除realloc
//----------------------------------------create data
data=(double *)malloc((ARSIZE+2)*sizeof(double)); // (double *) MSVC
double c; // data for save
int i;    // cycle variable
if ( data != NULL ) {
for(i=0;i<ARSIZE;i++){
  c=POOL+i;
  data[i]=c;
}
} else {
    free(data);
        printf("Error allocating memory!\n");
    return 1;
}

何时工作!

但为什么循环中的realloc是坏的?对于Win32来说是不好的。在Mac OS X上 - 确定

2 个答案:

答案 0 :(得分:1)

最重要的是,您要比较不同C ++运行时(libstd ++ vs msvcrt)的性能,而不是OS的性能。

内存分配有很多不同的策略。很难选择能够提供最大效用的分配策略,而不会过度惩罚某些行为。例如,某些策略允许您有效地分配数百万个小块,但它们在(重新)分配大量内存块时无效。

一般来说,假设分配小对象的效率不高,开发人员会尝试减少(重新)分配的数量。

另一点是当程序在调试模式下运行时,MSVC会进行一些内存检查。它显着减慢了程序的速度。检查您是否在发布模式下运行这两个版本。

从理论转向实践 - 总是尝试减少(重新)分配的数量:

double *data = (double*) malloc( ARSIZE );

for( i = 0; i < ARSIZE; ++i ) {
   data[i] = POOL + i;
   ...
}

答案 1 :(得分:0)

像这样使用std::vector

std::vector<double> data;
unsigned int reallocCount = 0;
for ( unsigned int i = 0; i < ARSIZE; ++i )
{
    double * p = i ? &data[0] : 0;
    data.push_back( POOL + i );
    if ( &data[0] != p )
        ++reallocCount;
}
data.push_back( 0 ); // what ever you wish to store +2 doubles for...
data.push_back( 0 );

很明显,你的Mac版本保留了比实际请求更大的内存块,这就是矢量为你做的。鉴于C ++是你的方法。重新分配ARSIZE次需要ARSIZE mallocmemcpy s,因此无法在不到1秒的时间内完成。

您应该将data == temp作为

进行测试
for ( ;; )
    if ( temp == data )
    {
        printf( "Didn't actually reallocate, they are same" );
    }else if ( temp )
    {
        data = temp;
    }else
    {
        free( data );
        printf("Error");
        return 1;
    }
}

希望这有帮助。

编辑:让它变得更有趣,我在那里reallocCount添加了。在我的机器上,我得到41而不是10M!