c++ - 為什麼分配堆內存要比分配堆棧內存快得多?




performance heap-memory (2)

我試圖在堆和堆棧內存中為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;
}

其他答案指出在向量構造函數中至少存在“隱藏”初始化。

但是你的例子有另一個問題:也許它甚至不能衡量你的想法。 在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 )及其文檔。


我只是一個初學者,但是讓我給出我理解的主要是為了測試自己。

int *p = new int[1e7];

你在堆上為1000萬個整數分配連續的內存。

vector<int> v(1e7);

你在堆棧內存上為 vector<int> 對象分配。 在該對象的成員中,有一個指向堆上的 int[1e7] 的指針,該指針也被分配。 此外,其中的所有值都使用 int() (使用0s)的值初始化。 參見 std::vector 構造函數(2)





stack-memory