हालाँकि @Marc ने (जो मुझे लगता है कि) एक उत्कृष्ट विश्लेषण है, कुछ लोगों को थोड़ा अलग कोण से चीजों पर विचार करना पसंद हो सकता है।
एक एक अलग करने के एक अलग तरीके पर विचार करना है। पुराने संग्रहण से सभी तत्वों को नए संग्रहण में तुरंत कॉपी करने के बजाय, एक समय में केवल एक तत्व की प्रतिलिपि बनाने पर विचार करें - यानी, हर बार जब आप एक पुश_बैक करते हैं, तो यह नए तत्व को नए स्थान पर जोड़ता है, और बिल्कुल एक मौजूदा प्रतिलिपि बनाता है पुराने स्थान से नए स्थान पर जाने वाला तत्व। 2 के विकास कारक को मानते हुए, यह बहुत स्पष्ट है कि जब नया स्थान भरा होता है, तो हमने पुराने स्थान से नए स्थान पर सभी तत्वों को कॉपी करना समाप्त कर दिया होगा, और प्रत्येक पुश_बैक में लगातार समय रहा होगा। उस बिंदु पर, हम पुरानी जगह को छोड़ देंगे, मेमोरी का एक नया ब्लॉक आवंटित करेंगे जो कि बड़े लाभ के रूप में दो बार था, और प्रक्रिया को दोहराता है।
बहुत स्पष्ट रूप से, हम इसे अनिश्चित काल तक जारी रख सकते हैं (या जब तक मेमोरी उपलब्ध है, वैसे भी) और हर पुश_बैक में एक नया तत्व जोड़ना और एक पुराने तत्व को कॉपी करना शामिल होगा।
एक विशिष्ट कार्यान्वयन में अभी भी समान संख्या में प्रतियां हैं - लेकिन एक बार में प्रतियां एक करने के बजाय, यह सभी मौजूदा तत्वों को एक बार में कॉपी करता है। एक तरफ, आप सही हैं: इसका मतलब यह है कि यदि आप push_back के अलग-अलग इनवॉइस को देखते हैं, तो उनमें से कुछ दूसरों की तुलना में काफी धीमी हो जाएंगे। यदि हम एक दीर्घकालिक औसत को देखते हैं, हालांकि, वेक्टर के आकार की परवाह किए बिना, पुश_बैक के प्रति आह्वान की नकल की मात्रा स्थिर रहती है।
यद्यपि यह कम्प्यूटेशनल जटिलता के लिए अप्रासंगिक है, मुझे लगता है कि यह इंगित करने के लायक है कि यह चीजों को करने के लिए फायदेमंद क्यों है क्योंकि वे एक तत्व को प्रति push_back की नकल करने के बजाय करते हैं, इसलिए प्रति पुश_बैक समय स्थिर रहता है। विचार करने के कम से कम तीन कारण हैं।
पहला केवल मेमोरी उपलब्धता है। नकल समाप्त होने के बाद ही पुरानी मेमोरी को अन्य उपयोगों के लिए मुक्त किया जा सकता है। यदि आप एक समय में केवल एक आइटम की प्रतिलिपि बनाते हैं, तो मेमोरी का पुराना ब्लॉक बहुत लंबे समय तक आवंटित रहेगा। वास्तव में, आपके पास एक पुराना ब्लॉक और एक नया ब्लॉक अनिवार्य रूप से हर समय आवंटित होगा। यदि आपने दो से छोटी वृद्धि कारक पर फैसला किया है (जो आप आमतौर पर चाहते हैं) तो आपको हर समय आवंटित की जाने वाली और भी अधिक मेमोरी की आवश्यकता होगी।
दूसरा, यदि आप एक समय में केवल एक पुराने तत्व की नकल करते हैं, तो सरणी में अनुक्रमित करना थोड़ा अधिक मुश्किल होगा - प्रत्येक अनुक्रमण ऑपरेशन को यह पता लगाना होगा कि दिए गए सूचकांक में तत्व वर्तमान में मेमोरी के पुराने ब्लॉक में है या नहीं नया। यह किसी भी तरह से बहुत जटिल नहीं है, लेकिन एक सरणी में अनुक्रमण जैसे प्राथमिक संचालन के लिए, लगभग किसी भी धीमी गति से महत्वपूर्ण हो सकता है।
तीसरा, सभी को एक साथ कॉपी करके, आप कैशिंग का बेहतर लाभ उठाते हैं। सभी को एक साथ कॉपी करते हुए, आप ज्यादातर मामलों में स्रोत और गंतव्य दोनों को कैश में होने की उम्मीद कर सकते हैं, इसलिए कैश मिस की लागत उन तत्वों की संख्या से अधिक होती है जो कैश लाइन में फिट होंगे। यदि आप एक समय में एक तत्व की प्रतिलिपि बनाते हैं, तो आपके द्वारा प्रतिलिपि किए जाने वाले प्रत्येक तत्व के लिए आसानी से कैश मिस हो सकता है। यह केवल निरंतर कारक को बदलता है, न कि जटिलता को, लेकिन यह अभी भी काफी महत्वपूर्ण हो सकता है - एक विशिष्ट मशीन के लिए, आप आसानी से 10 से 20 के कारक की उम्मीद कर सकते हैं।
यह शायद एक पल के लिए दूसरी दिशा पर विचार करने के लायक है: यदि आप वास्तविक समय की आवश्यकताओं के साथ एक प्रणाली डिजाइन कर रहे थे, तो यह अच्छी तरह से एक बार में सभी के बजाय केवल एक तत्व को कॉपी करने के लिए समझ में आता है। हालाँकि कुल गति कम हो सकती है (या नहीं भी हो सकती है), फिर भी आपके पास पुश_बैक के एकल निष्पादन के लिए लिए जाने वाले समय के लिए एक कठिन ऊपरी सीमा होगी - यह मानते हुए कि आपके पास वास्तविक समय का आवंटनकर्ता था (हालांकि, कई वास्तविक समय सिस्टम केवल स्मृति के गतिशील आवंटन को प्रतिबंधित करता है, कम से कम भागों में वास्तविक समय की आवश्यकताओं के साथ)।