[英]Why is allocating heap-memory much faster than allocating stack-memory?
我試圖在堆和堆棧內存中為10 ^ 7個整數分配空間,以查看哪個更快。 顯然,在堆內存中分配要快得多,但我不明白其中的原因。
#include <bits/stdc++.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main()
{
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int *p = new int[1e7];
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << duration / 1e6 << "\n"; // 5e-06
t1 = high_resolution_clock::now();
vector<int> v(1e7);
t2 = high_resolution_clock::now();
duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << duration / 1e6 << "\n"; // 0.112284
return 0;
}
new int[1e7]
為1e7 int
值分配空間,並且不初始化它們。
vector<int> v(1e7);
在堆棧上創建一個vector<int>
對象,該對象的構造函數為堆上的1e7 int
值分配空間。 它還將每個int
值初始化為0。
速度的差異是因為初始化。
要比較堆棧分配的速度,您需要在堆棧上分配一個數組:
int data[1e7];
但要注意:這很有可能會失敗,因為堆棧不足以容納那個大陣列。
我只是一個初學者,但是讓我給出我理解的主要是為了測試自己。
在
int *p = new int[1e7];
你在堆上為1000萬個整數分配連續的內存。
在
vector<int> v(1e7);
你在堆棧內存上為vector<int>
對象分配。 在該對象的成員中,有一個指向堆上的int[1e7]
的指針,該指針也被分配。 此外,其中的所有值都使用int()
(使用0s)的值初始化。 參見std::vector
構造函數(2) 。
其他答案指出在向量構造函數中至少存在“隱藏”初始化。
但是你的例子有另一個問題:也許它甚至不能衡量你的想法。 在C ++中對未經優化的代碼進行基准測試幾乎毫無意義,並且適當的時序優化代碼很難實現。
讓我們來看看Clang編譯的你的(可讀性修改)示例-O3
優化級別: godbolt鏈接 。
double test1() {
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int *p = new int[1e7];
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
return duration / 1e6; // 5e-06
}
編譯為:
test1(): # @test1()
push rbx
call std::chrono::_V2::system_clock::now()
mov rbx, rax
call std::chrono::_V2::system_clock::now()
sub rax, rbx
movabs rcx, 2361183241434822607
imul rcx
mov rax, rdx
shr rax, 63
sar rdx, 7
add rdx, rax
cvtsi2sd xmm0, rdx
divsd xmm0, qword ptr [rip + .LCPI0_0]
pop rbx
ret
.LCPI1_0:
.quad 4696837146684686336 # double 1.0E+6
第一部分甚至不叫操作員新! 編譯器通過您的程序看到並意識到您從未使用過已分配的數組,因此它從生成的可執
因此,當使用這樣的設置進行編譯時,程序的第一部分根本不會在堆上分配數組,從而使測量毫無意義。
我建議閱讀有關基准測試的內容,並使用專門的微基准框架來進行此類測試。 看一下Google Benchmark (和在線QuickBench )及其文檔。
我想指出堆棧分配在運行時完全沒有時間; 所有的工作都是由編譯器完成的。 無論優化如何,這種比較都毫無意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.