सबसे उपयोगी मामलों में से एक मुझे जाल और छवि प्रसंस्करण, भौतिकी इंजन और प्रदर्शन जैसे महत्वपूर्ण क्षेत्रों में काम करने वाली लिंक्डइन सूचियों के लिए मिलता है, जब लिंक की गई सूचियों का उपयोग वास्तव में संदर्भ के स्थानीयता में सुधार करता है और ढेर आवंटन को कम करता है और कभी-कभी इसकी तुलना में मेमोरी का उपयोग भी कम कर देता है सीधा विकल्प।
अब यह एक पूर्ण ऑक्सीमोरोन की तरह लग सकता है जो लिंक्ड लिस्ट सभी कर सकता है क्योंकि वे अक्सर विपरीत करने के लिए कुख्यात होते हैं, लेकिन उनके पास एक अद्वितीय संपत्ति होती है जिसमें प्रत्येक सूची नोड का एक निश्चित आकार और संरेखण आवश्यकताएं होती हैं जिन्हें हम अनुमति देने के लिए शोषण कर सकते हैं उन्हें संचरित रूप से संग्रहीत किया जाना चाहिए और निरंतर-समय पर उन तरीकों से हटाया जाना चाहिए जो चर-आकार की चीजें नहीं कर सकते हैं।
परिणामस्वरूप, एक ऐसा मामला लेते हैं जहां हम एक चर-लंबाई अनुक्रम को संग्रहीत करने के अनुरूप समतुल्य करना चाहते हैं जिसमें एक लाख नेस्टेड चर-लंबाई उप-अनुक्रम होते हैं। एक ठोस उदाहरण एक अनुक्रमित जाल है जिसमें एक लाख बहुभुज (कुछ त्रिकोण, कुछ क्वाड्स, कुछ पेंटागन, कुछ हेक्सागोन्स, आदि) और कभी-कभी बहुभुज को जाल में कहीं से हटा दिया जाता है और कभी-कभी बहुभुज को एक मौजूदा बहुभुज या एक वर्टेक्स डालने के लिए फिर से बनाया जाता है। एक हटाओ। उस मामले में, अगर हम एक लाख छोटे स्टोर करते हैं std::vectors
, तो हम हर एक वेक्टर के लिए ढेर के आवंटन के साथ-साथ संभावित विस्फोटक मेमोरी उपयोग का सामना करते हैं। एक लाख छोटे SmallVectors
को इस समस्या का सामना नहीं करना पड़ सकता है क्योंकि आम मामलों में, लेकिन फिर उनके प्रचारित बफर जो अलग से ढेर-आवंटित नहीं होते हैं, वे अभी भी विस्फोटक स्मृति उपयोग का कारण बन सकते हैं।
यहां समस्या यह है कि एक लाख std::vector
उदाहरण एक लाख चर-लंबाई वाली चीजों को संग्रहीत करने की कोशिश कर रहे हैं। परिवर्तनीय-लंबाई की चीजें एक ढेर आवंटन चाहती हैं क्योंकि वे बहुत प्रभावी ढंग से संचित रूप से संग्रहीत नहीं किए जा सकते हैं और निरंतर-समय में (बहुत जटिल आवंटनकर्ता के बिना कम से कम सीधे तरीके से) हटा दिए जाते हैं यदि वे अपनी सामग्री को कहीं और संग्रहीत नहीं करते हैं।
यदि, इसके बजाय, हम यह करते हैं:
struct FaceVertex
{
// Points to next vertex in polygon or -1
// if we're at the end of the polygon.
int next;
...
};
struct Polygon
{
// Points to first vertex in polygon.
int first_vertex;
...
};
struct Mesh
{
// Stores all the face vertices for all polygons.
std::vector<FaceVertex> fvs;
// Stores all the polygons.
std::vector<Polygon> polys;
};
... फिर हमने नाटकीय रूप से ढेर आवंटन और कैश मिस की संख्या को कम कर दिया है। हमारे द्वारा उपयोग किए जाने वाले हर एक बहुभुज के लिए ढेर आवंटन और संभावित अनिवार्य कैश की आवश्यकता के बजाय, हमें अब केवल उस ही आवंटन की आवश्यकता है जब पूरे जाल में संग्रहीत दो वैक्टर में से एक उनकी क्षमता (एक परिशोधित लागत) से अधिक हो। जबकि स्ट्राइड एक वर्टेक्स से अगले तक जाने के लिए अभी भी कैश मिक्स के अपने हिस्से का कारण हो सकता है, यह अभी भी अक्सर की तुलना में कम है अगर प्रत्येक एकल बहुभुज एक अलग डायनामिक सरणी संग्रहीत करता है क्योंकि नोड्स को आकस्मिक रूप से संग्रहीत किया जाता है और एक संभावना है कि एक पड़ोसी वर्टेक्स हो सकता है बेदखली से पहले पहुँचा जा सकता है (विशेष रूप से यह देखते हुए कि कई बहुभुज एक ही बार में अपने वर्टीकल जोड़ देंगे जो कि बहुभुज के सिंह के हिस्से को पूरी तरह से सन्निहित बनाता है)।
यहाँ एक और उदाहरण है:

... जहां ग्रिड कोशिकाओं का उपयोग कण-कण की टक्कर को तेज करने के लिए किया जाता है, कहते हैं, 16 मिलियन कण हर एक फ्रेम को आगे बढ़ाते हैं। उस कण ग्रिड उदाहरण में, लिंक की गई सूचियों का उपयोग करके हम केवल 3 सूचकांकों को बदलकर एक कण को एक ग्रिड कोशिका से दूसरे में स्थानांतरित कर सकते हैं। एक वेक्टर से मिटाकर और दूसरे को पीछे धकेलना काफी महंगा हो सकता है और अधिक ढेर आवंटन पेश कर सकता है। लिंक की गई सूचियाँ किसी सेल की मेमोरी को 32-बिट तक कम कर देती हैं। कार्यान्वयन के आधार पर एक वेक्टर, अपने गतिशील सरणी को उस बिंदु तक प्रचारित कर सकता है जहां यह एक खाली वेक्टर के लिए 32 बाइट्स ले सकता है। यदि हमारे पास लगभग एक लाख ग्रिड सेल हैं, तो यह काफी अंतर है।
... और यह वह जगह है जहाँ मुझे इन दिनों सबसे अधिक उपयोगी लिस्ट मिली हुई है, और मैं विशेष रूप से "इंडिकेटेड लिस्टेड लिस्ट" किस्म को उपयोगी मानता हूँ क्योंकि 32-बिट इंडेक्स 64-बिट मशीनों पर लिंक की मेमोरी आवश्यकताओं को आधा कर देता है और वे इसका मतलब है कि नोड्स को एक सरणी में आकस्मिक रूप से संग्रहीत किया जाता है।
अक्सर मैं उन्हें अनुक्रमित मुफ्त सूचियों के साथ जोड़ देता हूं ताकि कहीं भी निरंतर-समय निष्कासन और सम्मिलन की अनुमति मिल सके:

उस स्थिति में, next
इंडेक्स या तो अगले फ्री इंडेक्स की ओर इशारा करता है यदि नोड हटा दिया गया है या अगला उपयोग किया गया इंडेक्स यदि नोड को हटाया नहीं गया है।
और यह नंबर एक उपयोग मामला है जो मुझे इन दिनों लिंक की गई सूचियों के लिए मिला है। जब हम एक लाख परिवर्तनीय-लंबाई वाले उप-क्रमों को संग्रहीत करना, कहना चाहते हैं, तो 4 तत्व प्रत्येक, (लेकिन कभी-कभी तत्वों को हटा दिया जाता है और इन उप-अनुक्रमों में से एक में जोड़ा जाता है), लिंक की गई सूची हमें 4 मिलियन संग्रहीत करने की अनुमति देती है लिंक की गई सूची 1 मिलियन कंटेनरों के बजाय संक्रामक रूप से है जो प्रत्येक व्यक्तिगत रूप से ढेर-आबंटित हैं: एक विशाल वेक्टर, यानी एक मिलियन लोग नहीं हैं।