std :: array बनाम array performance


84

अगर मैं एक बहुत ही सरल सरणी बनाना चाहते हैं

int myArray[3] = {1,2,3};

क्या मुझे std::arrayइसके बजाय उपयोग करना चाहिए ?

std::array<int, 3> a = {{1, 2, 3}};

सामान्य लोगों पर std :: array का उपयोग करने के क्या फायदे हैं? क्या यह अधिक प्रदर्शनकारी है? बस कॉपी / एक्सेस के लिए संभालना आसान है?


2
std :: के साथ बहुआयामी सरणी को परिभाषित करना कठिन होगा
goGud

15
@goGud: मुश्किल नहीं है, बस और अधिक क्रिया।
माइक सेमोर

1
सूचक क्षय, एक संदर्भ आदि लेते हुए ..., सी-एरे के बारे में कई बातें अजीब हैं। सी-एरे के मामले में यह सूचक एक सूचक हो सकता है और for (auto i = ++std::begin(myArray); . . . संकलन भी नहीं कर सकता है (ऐसा लगता है कि मौलिक प्रकार के अस्थायी परस्पर भिन्न नहीं हैं, कम से कम क्लैंग 6 के साथ नहीं)
पैट्रिक फ्रेंबर्ग

आरंभिक रूप से जादुई रूप से भिन्न होते हैं: struct Direction { int32_t dw; int32_t dh; };और static const Direction DIRECTIONS[DIRECTIONS_COUNT] { { -1, 1}, {0,1}, {1,1} , { 1, 0 }, {1,-1}, {0,-1} , {-1,-1}, {-1,0} };संकलन। लेकिन अगर आप एक std::array<Direction,DIRECTIONS_COUNT>ही इनिशलाइज़र सूची के साथ बदलते हैं , तो अचानक आपको "बहुत अधिक इनिशियलाइज़र" त्रुटि मिलती है। (VS 2019 कम्युनिटी विथ लैंग्वेज = C ++ 17)
BitTickler

std::arrayआरंभ में डबल कोष्ठक क्यों ?
मार्क .377

जवाबों:


101

उपयोग करने के क्या फायदे हैं std::arrayसामान्य लोगों हैं?

इसमें अनुकूल मूल्य शब्दार्थ है, ताकि इसे मूल्य से फ़ंक्शन से पास या लौटाया जा सके। इसका इंटरफ़ेस आकार को खोजने के लिए इसे और अधिक सुविधाजनक बनाता है, और एसटीएल-स्टाइल इटेरेटर-आधारित एल्गोरिदम के साथ उपयोग करता है।

क्या यह अधिक प्रदर्शनकारी है?

यह बिल्कुल वैसा ही होना चाहिए। परिभाषा के अनुसार, यह एक साधारण समुच्चय है जिसमें इसके एकमात्र सदस्य के रूप में एक सरणी होती है।

बस कॉपी / एक्सेस के लिए संभालना आसान है?

हाँ।


41

एक std::arrayएक सी शैली सरणी के चारों ओर एक बहुत पतली आवरण है, मूल रूप से के रूप में परिभाषित

template<typename T, size_t N>
class array
{
public:
    T _data[N];
    T& operator[](size_t);
    const T& operator[](size_t) const;
    // other member functions and typedefs
};

यह एक समुच्चय है , और यह आपको इसे लगभग एक मौलिक प्रकार की तरह उपयोग करने की अनुमति देता है (यानी आप पास-बाय-वैल्यू, असाइन आदि कर सकते हैं, जबकि एक मानक सी सरणी को किसी अन्य सरणी में सीधे असाइन या कॉपी नहीं किया जा सकता है)। आपको कुछ मानक कार्यान्वयन पर ध्यान देना चाहिए (अपने पसंदीदा आईडीई से परिभाषा या सीधे खुले पर जाएं <array>), यह सी ++ मानक पुस्तकालय का एक टुकड़ा है जो पढ़ने और समझने में काफी आसान है।


24

std::array सी सरणियों के लिए शून्य-ओवरहेड रैपर के रूप में डिज़ाइन किया गया है जो इसे अन्य सी ++ कंटेनरों के शब्दार्थ की तरह "सामान्य" मान देता है।

आपको अतिरिक्त प्रदर्शन का आनंद लेने के लिए रनटाइम प्रदर्शन में कोई अंतर नहीं दिखना चाहिए।

यदि आपके पास C ++ 11 है या हाथ में बढ़ावा है, तो शैली सरणियों के std::arrayबजाय का उपयोग करना int[]एक अच्छा विचार है।


10

क्या यह अधिक प्रदर्शनकारी है?

यह बिल्कुल वैसा ही होना चाहिए। परिभाषा के अनुसार, यह एक साधारण समुच्चय है जिसमें इसके एकमात्र सदस्य के रूप में एक सरणी होती है।

स्थिति अधिक जटिल लगती है, जैसे std::array हमेशा विशिष्ट प्लेटफॉर्म के आधार पर सी-सरणी की तुलना में समान असेंबली कोड का उत्पादन नहीं होता है।

मैंने गॉडबोल्ट पर इस विशिष्ट स्थिति का परीक्षण किया :

#include <array>
void test(double* const C, const double* const A,
          const double* const B, const size_t size) {
  for (size_t i = 0; i < size; i++) {
    //double arr[2] = {0.e0};//
    std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
    for (size_t j = 0; j < size; j++) {
      arr[0] += A[i] * B[j];
      arr[1] += A[j] * B[i];
    }
    C[i] += arr[0];
    C[i] += arr[1];
  }
}

GCC और Clang , C-array संस्करण और a दोनों के लिए समान असेंबली कोड का उत्पादन करते हैंstd::array

MSVC और ICPC , हालांकि, प्रत्येक सरणी संस्करण के लिए अलग-अलग असेंबली कोड का उत्पादन करते हैं। (मैंने ICPC19 का परीक्षण किया -Ofastऔर -Os, MSVC -Oxऔर -Os)

मुझे पता नहीं है, ऐसा क्यों है (मैं वास्तव में std के समान व्यवहार की उम्मीद करूंगा :: सरणी और सी-सरणी)। हो सकता है कि अलग-अलग अनुकूलन रणनीतियाँ कार्यरत हों।

थोड़ा अतिरिक्त के रूप में: ICPC में एक बग के साथ लगता है

#pragma simd 

कुछ स्थितियों में सी-सरणी का उपयोग करते समय वेक्टरकरण के लिए (सी-सरणी कोड एक गलत आउटपुट उत्पन्न करता है; std::arrayसंस्करण ठीक काम करता है)।

दुर्भाग्य से, मेरे पास अभी तक उस के लिए एक न्यूनतम काम करने का उदाहरण नहीं है, क्योंकि मैंने कोड की काफी जटिल टुकड़े को अनुकूलित करते हुए उस समस्या का पता लगाया था।

मैं इंटेल को बग-रिपोर्ट दर्ज करूंगा जब मुझे यकीन हो जाएगा कि मैंने सी-सरणी / std::arrayऔर के बारे में कुछ गलत नहीं समझा #pragma simd


1
संकलक बग के रूप में माना जा सकता है?
ओजोनऑग

8

std::arrayमूल्य शब्दार्थ है जबकि कच्ची सरणियाँ नहीं है। इसका मतलब है आप कॉपी कर सकते हैंstd::array इसे एक आदिम मूल्य की तरह और ट्रीट । आप उन्हें फ़ंक्शन तर्क के रूप में मान या संदर्भ द्वारा प्राप्त कर सकते हैं और आप उन्हें मूल्य द्वारा वापस कर सकते हैं।

यदि आप कभी भी कॉपी नहीं करते हैं std::array, तो कच्चे सरणी की तुलना में कोई प्रदर्शन अंतर नहीं है। यदि आपको प्रतियां बनाने की आवश्यकता है, तो std::arrayसही काम करेंगे और अभी भी समान प्रदर्शन देना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.