2010-02-14 25 views
5

consideremos siguientes dos códigosasignación dinámica de la memoria

Primero:

for (int i=0;i<10000000;i++) 
{ 
    char* tab = new char[500]; 
    delete[] tab; 
} 

Segundo: el uso de memoria

for (int i=0;i<10000000;i++) 
{ 
    char tab[500]; 
} 

El pico es casi el mismo, pero el segundo código se ejecuta alrededor del 20 veces más rápido que el primero.

Pregunta
¿Es porque en la primera matriz de código se almacena en el montón, y en la segunda matriz se almacena en la pila?

Respuesta

2

Sí. la asignación de matrices en el montón es mucho, mucho más lenta que crearlas automáticamente. El primero puede implicar una llamada al sistema, y ​​siempre implicará la manipulación de estructuras de montón, mientras que el segundo simplemente ajusta el puntero de pila.

1

Solo para confirmar 2 respuestas anteriores, al crear un perfil de dicho código (en Visual Studio) y observar el código ensamblador, primero llama al operador nuevo y no al segundo, lo que significa que se asigna automáticamente en la pila.

Así es como se ve

int _tmain(int argc, _TCHAR* argv[]) 
{ 
00401000 push  ebp 
00401001 mov   ebp,esp 
00401003 sub   esp,304h 
00401009 push  ebx 
0040100A push  esi 
0040100B push  edi 
0040100C lea   edi,[ebp-304h] 
00401012 mov   ecx,0C1h 
00401017 mov   eax,0CCCCCCCCh 
0040101C rep stos dword ptr es:[edi] 
    for (int i=0;i<10000;i++) 
0040101E mov   dword ptr [i],0 
00401025 jmp   wmain+30h (401030h) 
00401027 mov   eax,dword ptr [i] 
0040102A add   eax,1 
0040102D mov   dword ptr [i],eax 
00401030 cmp   dword ptr [i],2710h 
00401037 jge   wmain+6Fh (40106Fh) 
    { 
     char* tab = new char[500]; 
00401039 push  1F4h 
0040103E call  operator new[] (4010F0h) 
00401043 add   esp,4 
00401046 mov   dword ptr [ebp-300h],eax 
0040104C mov   eax,dword ptr [ebp-300h] 
00401052 mov   dword ptr [tab],eax 
     delete[] tab; 
00401055 mov   eax,dword ptr [tab] 
00401058 mov   dword ptr [ebp-2F4h],eax 
0040105E mov   ecx,dword ptr [ebp-2F4h] 
00401064 push  ecx 
00401065 call  operator delete[] (401104h) 
0040106A add   esp,4 
    } 
0040106D jmp   wmain+27h (401027h) 

    for (int i=0;i<10000;i++) 
0040106F mov   dword ptr [i],0 
00401076 jmp   wmain+81h (401081h) 
00401078 mov   eax,dword ptr [i] 
0040107B add   eax,1 
0040107E mov   dword ptr [i],eax 
00401081 cmp   dword ptr [i],2710h 
00401088 jge   wmain+8Ch (40108Ch) 
    { 
     char tab[500]; 
    } 
0040108A jmp   wmain+78h (401078h) 

    return 0; 
0040108C xor   eax,eax 
} 
1

¿Usted intentó funcionando con optimizaciones encendido? Sería muy sorprendido si hubo alguna diferencia después de que el optimizador se active. De hecho, esperaría que el optimizador elimine el ciclo completamente en ambos casos.

+0

No he intentado compilarlo con optimizaciones, porque no era el objetivo. Solo quería estar seguro de por qué el segundo código es mucho más rápido. –

+0

¿Por qué esperas que elimine el nuevo bucle []/delete []? Optimizar una llamada a una función con un enlace externo (y efectos secundarios) suena como algo peligroso de hacer. – bk1e

+0

No es una función, simplemente un bucle que obviamente no hace nada. –

Cuestiones relacionadas