2010-02-14 45 views
5

Cho phép xem xét sau hai mãphân bổ động của bộ nhớ

Đầu tiên:

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

Thứ hai: sử dụng bộ nhớ

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

Đỉnh là gần như giống nhau, nhưng mã thứ hai chạy khoảng 20 nhanh hơn lần đầu tiên.

Câu hỏi
Có phải vì mảng mã đầu tiên được lưu trữ trên heap và trong mảng thứ hai được lưu trữ trên ngăn xếp?

Trả lời

5

Có phải vì mảng mã đầu tiên được lưu trữ trên heap và trong mảng thứ hai được lưu trữ trên ngăn xếp?

Có, phân bổ ngăn xếp nhanh hơn nhiều vì tất cả mẫu mã thứ hai đang làm là di chuyển (thêm/bớt) con trỏ ngăn xếp thay vì thao tác đống.

Nếu bạn muốn biết thêm, hai câu hỏi này bao gồm các chủ đề

2

Yes. phân bổ mảng trên heap là nhiều, chậm hơn nhiều so với việc tạo chúng tự động. Trước đây có thể liên quan đến một cuộc gọi hệ thống, và sẽ luôn luôn liên quan đến thao tác cấu trúc heap, trong khi sau này chỉ cần điều chỉnh con trỏ ngăn xếp.

1

Chỉ cần xác nhận 2 câu trả lời trước đó, khi lược tả mã như vậy (trong Visual Studio), và xem mã lắp ráp, đầu tiên gọi toán tử mới và thứ hai không có nghĩa là được cấp phát tự động trên ngăn xếp.

Sau đây là cách có vẻ

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

Bạn hãy thử cho nó chạy với tối ưu hóa bật? Tôi sẽ là rất ngạc nhiên nếu có bất kỳ sự khác biệt nào sau khi trình tối ưu hóa khởi động. Trong thực tế, tôi hy vọng trình tối ưu hóa sẽ xóa vòng lặp hoàn toàn trong cả hai trường hợp.

+0

Tôi chưa cố gắng biên dịch nó bằng các tối ưu hóa, vì đó không phải là mục đích. Tôi chỉ muốn chắc chắn tại sao mã thứ hai nhanh hơn nhiều. –

+0

Tại sao bạn mong đợi nó xóa vòng lặp []/xóa [] mới? Tối ưu hóa một cuộc gọi đến một chức năng với liên kết bên ngoài (và tác dụng phụ) nghe như một điều nguy hiểm để làm. – bk1e

+0

Nó không phải là một chức năng - chỉ là một vòng lặp mà rõ ràng là không có gì. –

Các vấn đề liên quan