2010-04-06 14 views
5

मेरा आवेदन टीएलिस्ट का भारी उपयोग करता है, इसलिए मैं सोच रहा था कि क्या कोई वैकल्पिक कार्यान्वयन है जो विशेष उपयोग मामले के लिए तेज़ या अनुकूलित है।क्या कोई तेज टीएलआईएस कार्यान्वयन है?

मुझे RtlVCLOptimize.pas 2.77 पता है, जिसने कई टीएलआईस्ट विधियों के कार्यान्वयन को अनुकूलित किया है।

लेकिन मैं जानना चाहता हूं कि वहां कुछ और है या नहीं। मुझे इसे एक टीएलआईस्ट वंश होने की भी आवश्यकता नहीं है, मुझे इसे लागू करने के तरीके के बावजूद टीएलआईस्ट कार्यक्षमता की आवश्यकता है।

यह पूरी तरह से संभव है, मूलभूत कार्यक्षमता टीएलआईस्ट प्रदान करता है, कि सुधार के लिए बहुत अधिक जगह नहीं है, लेकिन फिर भी यह सवाल सत्यापित करना चाहेंगे।

संपादित करें: मेरे विशेष उपयोग मामले में कोई सूचियां हल नहीं की जाती हैं। इसमें बहुत सारी सूचियां हैं, जिनमें विभिन्न तत्व हैं। मैंने टीएलआईस्ट को अपनी खुद की कक्षा से बदल दिया है ताकि कॉल जोड़ें/निकालें और तत्वों की गिनती दर्ज की जा सके।

ListAdd = 15766012; ListRemove = 10630000; ListCount = 5136012 

मैं यह भी मिल सकता है क्या एक ही सूची में तत्वों की सबसे बड़ी संख्या है: यह (सभी सूचियों के लिए toatal) की रिपोर्ट है।

मेरे पास कोई विशेष समस्या नहीं है, मुझे आश्चर्य है कि इन नंबरों के साथ-साथ यह भी तेजी से बनाने का कोई तरीका है, यहां तक ​​कि छोटे सुधार भी शामिल होंगे।

+1

कितने आइटम, क्रमबद्ध या नहीं, और आपकी विशेष चिंता क्या है? यानी 10,000+ पंक्तियों के साथ बहुत धीमी है? –

+0

क्या आप जोड़ें, निकालें और गिनती से किसी भी अन्य तरीकों का उपयोग करते हैं? – Harriv

+1

बीटीडब्ल्यू पर डेल्फी का कौन सा संस्करण है? –

उत्तर

8

टीएलिस्ट के बारे में मुझे पता चलने वाली सबसे बड़ी बाधाओं में से एक बड़ी सूची में हटाएं/निकालें। आइटम को हटाने [0] आइटम को हटाने की तुलना में बहुत धीमी है [गणना -1] इसके बाद मेमोरी चाल की वजह से।

उदाहरण के लिए, 65536 तत्वों से युक्त एक सूची पर:

while list.Count > 0 do List.Delete(0) //Takes 2 mins to complete 

for I := List.Count-1 downto 0 do List.Delete(I) //Takes less than 1 sec 

तो अगर आप तत्वों के लाखों लोगों के साथ एक TList, एक कम सूचकांक आइटम को हटाने प्रदर्शन के लिहाज से महंगा हो सकता है।साथ ही, इस बात पर विचार करें कि ऐसी कोई सूची नहीं है जो क्रमबद्ध नहीं है, इसमें तत्व को ढूंढना बहुत धीमा हो जाता है। बड़ी सूची में इंडेक्सऑफ बहुत धीमी है। आप सूची को क्रमबद्ध रखने पर विचार करना चाहेंगे।

इसके अलावा, आपके आइटम की गणना पर विचार करना काफी बड़ा हो सकता है, आप अपने तत्वों को स्टोर करने के लिए टीएलिस्ट की एक सूची का उपयोग करने पर विचार करना चाहेंगे, जो पहले से उल्लिखित हटाए गए/निकालने वाले ओवरहेड को कम करने में मदद करेगा।

1

सबसे तेज़ डेटा संरचना आमतौर पर डेटा संरचना नहीं होती है, बल्कि इसके बजाय एक नकली जो डेटा की आवश्यकता होती है, जैसे Virtual Treeview करता है। शायद आप किसी प्रकार की टीवीर्टुअललिस्ट लिख सकते हैं जो आवश्यक कार्यों को इकट्ठा करने के लिए उपयुक्त कार्यों को कॉल करता है जब तत्वों का अनुरोध किया जाता है।

+1

एक प्रदर्शन बिंदु से जो एक अच्छा विचार नहीं हो सकता है: टीएलिस्ट स्मृति के एक ब्लॉक से पढ़ता है, डेटा को बनाने के लिए "कॉलबैक" विधि को कॉल करने के रूप में आप सूची के साथ काम कर रहे हैं, संभवतः तेज़ नहीं हो सकता है। इस विचार के साथ दूसरी समस्या यह है कि आम तौर पर डेटा "बना" नहीं होता है, और मुझे संदेह है कि इसे "फ्लाई पर" बनाया जा सकता है। वर्चुअल ट्री-जैसे जीयूआई का मानना ​​है कि कुछ अंतर्निहित डेटा संरचना है जिसमें डेटा है और वे आवश्यकतानुसार डेटा प्राप्त करने के लिए एक विधि कहते हैं। वे स्मृति में डेटा के डुप्लिकेशन से बचने के लिए ऐसा करते हैं (और वे तेज़ होते हैं क्योंकि वे डेटा डुप्लिकेट नहीं करते हैं)। –

7

ऐसा लगता है कि आप बहुत सारे जोड़ रहे हैं। मुझे नहीं पता कि कितनी सूचियां फैली हुई हैं, लेकिन यदि आपकी व्यक्तिगत सूचियां बहुत बड़ी हो रही हैं, तो आप एक सूची को लागू करना चाहेंगे जो तेजी से बढ़ता है।

TList.Grow पर एक नज़र डालें, जिसे आप किसी आइटम में किसी आइटम को जोड़ने का प्रयास करते हैं, जहां इसके सभी सरणी तत्व उपयोग में हैं, और आप देखेंगे कि यह 25% तक बढ़ता है। यह मेमोरी उपयोग को उचित स्तर पर रखना है। लेकिन अगर आपको वास्तव में बड़ी सूचियों की आवश्यकता है, तो अपनी खुद की वंशज वर्ग बनाएं और ओवरराइड करें ताकि दूसरी पंक्ति में Delta := FCapacity div 4 के बजाय यह Delta := FCapacity कहता है। इससे आपकी सूची हर बार बड़ी बार बढ़ती है, जिसका अर्थ है कम रीलॉक्स और कम प्रतियां।

लेकिन जो चीज शायद आपको मार रही है वह सभी कॉल निकालें। इसे निकालने से पहले आइटम को निकालना है, जिसमें इंडेक्सऑफ को कॉल करना शामिल है, जो पूरे सरणी का रैखिक स्कैन है। अगर आपके पास बड़ी सूची है और आप बहुत सारे रिमूव कर रहे हैं, तो यह आपके प्रदर्शन को मारने वाला है।

इन सूचियों का उपयोग आप विशेष रूप से बड़े लोगों के लिए क्या कर रहे हैं? आप उनके साथ क्या कर रहे हैं, इस पर निर्भर करते हुए, नौकरी के लिए बेहतर डेटा संरचनाएं हो सकती हैं।

+3

ओवरराइडिंग ग्रो एक अच्छा सुझाव है। वैकल्पिक रूप से, सूची। क्षमता सेट की जा सकती है जब सूची बनाई जाती है जो बहुत सारे realloc को भी बचाएगा। –

+0

हाँ, यह भी एक अच्छा विचार है, खासकर यदि आपके पास एक अच्छा अनुमान है कि सूची कितनी वस्तुओं को पकड़ने के लिए खत्म हो जाएगी। –

+1

संबंधित विचार: आइटम को हटाए जाने के रूप में चिह्नित करने का अवसर हो सकता है, और फिर वास्तव में हटाने के बजाय उन्हें फिर से उपयोग करें। केवल उपयोगी अगर आपको "खुले" (चिह्नित हटाए गए) आइटम की खोज करने में बहुत समय व्यतीत नहीं करना पड़ेगा। –

6

आप प्रक्रिया को सूचित करें का उपयोग कर रहे हैं? यदि नहीं, तो अपना खुद का टीएलआईस्ट कार्यान्वयन करें। अधिसूचना प्रक्रिया के कारण, TList.Clear (जिसे विनाश पर कहा जाता है) एक ओ (एन) ऑपरेशन है। TList.Clear विधि SetCount को कॉल करता है जो बदले में सभी आइटमों के लिए हटाएं कॉल करता है ताकि प्रत्येक हटाए गए आइटम के लिए अधिसूचना प्रक्रिया को बुलाया जा सके। जब आपको अधिसूचना विधि को ओवरराइड करने की आवश्यकता नहीं है, तो आप हटाएं कॉल करने के लिए SetCount प्रक्रिया को समायोजित कर सकते हैं। यह आपको 15.766.012 का समय बचा सकता है - 10.630.000 = 5.136.012 कॉल हटाएं।

एनबी: प्रदर्शन हासिल रूप में मेसन व्हीलर ने सुझाव दिया आप अपने सूची को क्रमबद्ध करने और अपने निकालें प्रक्रिया अनुकूलन द्वारा प्राप्त प्रदर्शन लाभ आपको मिल के रूप में बड़ा नहीं होगा। जब तक आपकी सूची में बहुत कम संख्या में आइटम नहीं होते हैं और तुलना फ़ंक्शन में बहुत समय लगता है।

+0

अच्छा बिंदु, हालांकि यह ध्यान देने योग्य है कि यदि यह एक टॉब्जेक्टलिस्ट है और न केवल एक वेनिला टीएलिस्ट है, तो अधिसूचना को वहां होना चाहिए। यदि नहीं, हालांकि, अधिसूचना का उपयोग करने का कोई अच्छा कारण नहीं है। –

संबंधित मुद्दे