जबसे
- वे दोनों सन्निहित मेमोरी कंटेनर हैं;
- बुद्धिमान के रूप में, deque में लगभग सब कुछ वेक्टर है, लेकिन अधिक है, क्योंकि यह सामने से सम्मिलित करने के लिए अधिक कुशल है।
क्यों किसी को भी पसंद करते std::vectorहैं std::deque?
जबसे
क्यों किसी को भी पसंद करते std::vectorहैं std::deque?
जवाबों:
स्मृति में तत्व तत्व सन्निहित नहींdeque हैं ; तत्वों को होने की गारंटी है। इसलिए यदि आपको एक सादे सी लाइब्रेरी के साथ बातचीत करने की आवश्यकता है जो कि सन्निहित सरणियों की आवश्यकता है, या यदि आप स्थानिक इलाके के बारे में परवाह करते हैं (बहुत कुछ), तो आप पसंद कर सकते हैं । इसके अलावा, चूंकि कुछ अतिरिक्त बहीखाता पद्धति है, इसलिए अन्य ऑप्स अपने समकक्ष संचालन की तुलना में संभवतः (थोड़ा) अधिक महंगे हैं । दूसरी ओर, कई / बड़े उदाहरणों का उपयोग करने से अनावश्यक हीप विखंडन (कॉल को धीमा करना ) हो सकता है।vectorvectorvectorvectornew
इसके अलावा, जैसा कि स्टैकऑवरफ्लो पर कहीं और बताया गया है , यहाँ और भी अच्छी चर्चा है: http://www.gotw.ca/gotw/054.htm ।
अंतर जानने के लिए पता होना चाहिए कि dequeआम तौर पर कैसे लागू किया जाता है। मेमोरी को समान आकारों के ब्लॉकों में आवंटित किया जाता है, और वे एक साथ जंजीर (एक सरणी या संभवतः एक वेक्टर के रूप में) होते हैं।
तो nth तत्व को खोजने के लिए, आप उपयुक्त ब्लॉक को खोजते हैं और फिर उसके भीतर के तत्व को एक्सेस करते हैं। यह निरंतर समय है, क्योंकि यह हमेशा 2 लुकअप होता है, लेकिन यह अभी भी वेक्टर से अधिक है।
vectorएपीआई के साथ भी अच्छी तरह से काम करता है जो एक सन्निहित बफर चाहते हैं क्योंकि वे या तो सी एपीआई हैं या एक पॉइंटर और लंबाई लेने में सक्षम होने में अधिक बहुमुखी हैं। (इस प्रकार आप एक वेक्टर के नीचे या एक नियमित सरणी रख सकते हैं और अपने मेमोरी ब्लॉक से एपीआई कॉल कर सकते हैं)।
dequeइसके सबसे बड़े फायदे कहां हैं:
इनमें से दूसरा कम ज्ञात है, लेकिन बहुत बड़े संग्रह के आकार के लिए:
जब मैं अतीत में बड़े संग्रह के साथ काम कर रहा था और एक सन्निहित मॉडल से ब्लॉक मॉडल में चला गया, तो हम 32-बिट सिस्टम में मेमोरी से बाहर भाग जाने से पहले लगभग 5 गुना बड़े संग्रह को स्टोर करने में सक्षम थे। यह आंशिक रूप से है, क्योंकि जब पुन: आवंटन होता है, तो वास्तव में पुराने ब्लॉक को संग्रहीत करने की आवश्यकता होती है और तत्वों को कॉपी करने से पहले नया भी होता है।
यह सब कहने के बाद, आप उन std::dequeसिस्टम पर मुसीबत में पड़ सकते हैं जो "आशावादी" मेमोरी आवंटन का उपयोग करते हैं। vectorवसीयत के पुन: आवंटन के लिए एक बड़े बफर आकार का अनुरोध करने के अपने प्रयासों के बावजूद , शायद कुछ के साथ एक बिंदु पर अस्वीकार कर दिया जाएगा bad_alloc, आवंटनकर्ता की आशावादी प्रकृति हमेशा एक ए के द्वारा अनुरोध किए गए छोटे बफर के लिए अनुरोध देने की dequeसंभावना है और इसके कारण होने की संभावना है ऑपरेटिंग सिस्टम कुछ मेमोरी प्राप्त करने की कोशिश करने के लिए एक प्रक्रिया को मारने के लिए। जो भी इसे चुनता है वह बहुत सुखद नहीं हो सकता है।
ऐसे मामले में वर्कअराउंड या तो आशावादी आवंटन (हमेशा संभव नहीं) को ओवरराइड करने के लिए सिस्टम-स्तरीय झंडे स्थापित कर रहे हैं या स्मृति को कुछ और मैन्युअल रूप से प्रबंधित कर रहे हैं, जैसे कि अपने स्वयं के आवंटन का उपयोग करके जो मेमोरी उपयोग या समान के लिए जांच करता है। जाहिर है आदर्श नहीं। (जो सदिश पसंद करने के लिए आपके प्रश्न का उत्तर दे सकता है ...)
मैंने कई बार वेक्टर और डेक्स दोनों को लागू किया है। एक कार्यान्वयन के दृष्टिकोण से हिच बहुत अधिक जटिल है। यह जटिलता अधिक कोड और अधिक जटिल कोड का अनुवाद करती है। जब आप वेक्टर से अधिक डिस्क चुनते हैं तो आपको आमतौर पर एक कोड आकार हिट दिखाई देगा। यदि आपके कोड में सदिश एक्सेल (यानी पुश_बैक) का उपयोग किया जाता है, तो आपको एक छोटी गति हिट का भी अनुभव हो सकता है।
यदि आपको एक डबल एंडेड कतार की आवश्यकता है, तो डीक स्पष्ट विजेता है। लेकिन अगर आप अपने अधिकांश आवेषण कर रहे हैं और पीछे हट रहे हैं, तो वेक्टर स्पष्ट विजेता बनने जा रहा है। जब आप अनिश्चित हो जाते हैं, तो अपने कंटेनर को एक टाइपडिफ के साथ घोषित करें (ताकि आगे और पीछे स्विच करना आसान हो), और माप करें।
vector।) मैंने अपने जवाब में नीचे से जुड़ा एक कार्यान्वयन लिखा है । यह उतनी ही तेजी से हो सकता है, vectorलेकिन बहुत अधिक व्यापक रूप से लागू (जैसे, तेज कतार बनाते समय)।
std::dequeनिरंतर मेमोरी की गारंटी नहीं है - और यह अक्सर अनुक्रमित पहुंच के लिए कुछ धीमा है। एक छलावा को आमतौर पर "वेक्टर की सूची" के रूप में लागू किया जाता है।
Http://www.cplusplus.com/reference/stl/deque/ के अनुसार , "वैक्टर के विपरीत, देवताओं को सन्निहित भंडारण स्थानों में अपने सभी तत्वों को रखने की गारंटी नहीं है, इस प्रकार सूचक अंकगणित के माध्यम से सुरक्षित पहुंच की संभावना समाप्त हो जाती है।"
भाग थोड़े अधिक जटिल होते हैं, क्योंकि वे जरूरी नहीं कि एक सन्निहित स्मृति लेआउट हो। यदि आपको उस सुविधा की आवश्यकता है, तो आपको एक deque का उपयोग नहीं करना चाहिए।
(पहले, मेरे जवाब में मानकीकरण की कमी थी (ऊपर से उसी स्रोत से, "विशिष्ट पुस्तकालयों द्वारा विभिन्न तरीकों से देवताओं को लागू किया जा सकता है"), लेकिन यह वास्तव में किसी भी मानक पुस्तकालय डेटा प्रकार के बारे में लागू होता है।)
std::dequeसे कम मानकीकृत नहीं है std::vector। मेरा मानना है कि जटिल आवश्यकताओं को जटिल std::dequeभंडारण से पूरा किया जा सकता है।
dequeसन्निहित भंडारण के साथ कौन सी जटिलता आवश्यकताओं को पूरा नहीं किया जा सकता है?
deque, अर्थात् सिरों पर सम्मिलन मौजूदा तत्वों को संदर्भित नहीं करेगा । इस आवश्यकता का तात्पर्य है बंद स्मृति।
मुझे लगता है कि प्रत्येक मामले का सही परीक्षण करने के लिए अच्छा विचार है। और इस परीक्षण पर भरोसा करने का निर्णय लें।
मैं पसंद करते हैं std::dequeकी तुलना में std::vectorज्यादातर मामलों में।
vector। हम यह अनुमान लगा सकते हैं कि कोरोलरी क्यों नहीं है। यह कहना कि आप dequeअनिर्दिष्ट परीक्षणों से, अज्ञात कारणों से, पसंद करते हैं , एक उत्तर नहीं है।
आप इन परीक्षण परिणामों (स्रोत के साथ) को रिकॉर्ड करने के लिए वेक्टर को बहाना पसंद नहीं करेंगे ।
बेशक, आपको अपने ऐप / वातावरण में परीक्षण करना चाहिए, लेकिन सारांश में:
एक तरफ, सदिश काफी अक्सर सादा है, जो छल से तेज है। यदि आपको वास्तव में छल की सभी विशेषताओं की आवश्यकता नहीं है, तो वेक्टर का उपयोग करें।
दूसरी ओर, कभी-कभी आपको ऐसे फीचर्स की जरूरत होती है, जो वेक्टर आपको नहीं देता है, इस स्थिति में आपको एक डीके का उपयोग करना चाहिए। उदाहरण के लिए, मैं किसी को भी इस कोड को फिर से लिखने का प्रयास करता हूं , बिना किसी छल का उपयोग किए और एल्गोरिथ्म में भारी फेरबदल किए बिना।
push_backऔर pop_backसंचालन, deque<int>कम से कम 20% से अधिक तेजी से हमेशा होता है vector<int>मेरी परीक्षण (ओ 3 के साथ जीसीसी) में। मुझे लगता है यही कारण dequeहै कि चीजों के लिए मानक पसंद है std::stack...
ध्यान दें कि सरणी के बढ़ने पर वेक्टर मेमोरी फिर से आवंटित की जाती है। यदि आपके पास वेक्टर तत्वों के संकेत हैं, तो वे अमान्य हो जाएंगे।
साथ ही, यदि आप किसी तत्व को मिटाते हैं, तो पुनरावृत्तियाँ अमान्य हो जाती हैं (लेकिन "for (auto ...)") नहीं।
संपादित करें: 'deque' को 'वेक्टर' में बदला
std::dequeबहुत छोटा अधिकतम ब्लॉक आकार है (~ 16 बाइट्स, अगर मुझे सही याद है; शायद 32), और जैसे कि यथार्थवादी अनुप्रयोगों के लिए बहुत अच्छा प्रदर्शन नहीं करता है। एकdeque<T>जहांsizeof(T) > 8(या 16? यह एक छोटी संख्या है) एक के रूप में ही प्रदर्शन विशेषताओं के बारे में हैvector<T*>, जहां प्रत्येक तत्व गतिशील आवंटित किया जाता है। अन्य कार्यान्वयन में अलग-अलग अधिकतम ब्लॉक आकार होते हैं, इसलिए विभिन्न प्लेटफार्मों पर अपेक्षाकृत समान प्रदर्शन विशेषताओं वाले कोड लिखना मुश्किल होता हैdeque।