c++ - ढेर-मेमोरी को आवंटित करने की तुलना में ढेर-मेमोरी को क्यों आवंटित किया जाता है?




performance heap-memory (2)

अन्य उत्तर बताते हैं कि वेक्टर कंस्ट्रक्टर में कम से कम "छिपी" इनिशियलाइज़ेशन है।

लेकिन आपके उदाहरण में एक और समस्या है: शायद यह भी नहीं मापता कि आप क्या सोचते हैं। C ++ में बेंचमार्किंग अडॉप्टिमाइज्ड कोड बहुत ज्यादा अर्थहीन है और ठीक से टाइम ऑप्टिमाइज्ड कोड कठिन है।

आइए क्लैग द्वारा -O3 अनुकूलन स्तर: गॉडबोल्ट लिंक द्वारा संकलित आपके (पठनीयता के लिए संशोधित) उदाहरण पर एक नज़र डालें।

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 बेंचमार्क (और ऑनलाइन QuickBench ) पर एक नज़र डालें और यह प्रलेखन है।

मैंने ढेर में 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;
}

मैं केवल एक शुरुआत कर रहा हूं, लेकिन मुझे वह देना चाहिए जो मैं मुख्य रूप से खुद को परखने के लिए समझता हूं।

में

int *p = new int[1e7];

आप ढेर पर 10 मिलियन पूर्णांकों के लिए लगातार मेमोरी आवंटित कर रहे हैं।

में

vector<int> v(1e7);

आप एक vector<int> ऑब्जेक्ट के लिए स्टैक मेमोरी पर आवंटित कर रहे हैं। उस ऑब्जेक्ट के सदस्यों के बीच ढेर पर एक int[1e7] लिए एक संकेतक है, जिसे भी आवंटित किया गया है। इसके अलावा, इसमें सभी मान int() (0s के साथ int() के मान के साथ आरंभीकृत होते हैं। देखें निर्माता (2) का std::vector






stack-memory