2011-12-13 16 views
11

स्वीकृत ज्ञान यह है कि Dim dict As New Dictionary जैसे निर्माण का उपयोग Dim dict As Dictionary/Set dict = New Dictionary से प्रदर्शन में गरीब है।क्या एक्सेल वीबीए का खराब प्रदर्शन एक मिथक को ऑटो-इंस्टेंसिंग कर रहा है?

स्पष्टीकरण यह है कि पूर्व उदाहरण - ऑटो-इंस्टेंटेशन - परिवर्तनीय dict के पहले उपयोग तक तत्कालता को रोकता है। और इस प्रकार, हर बार निर्देश का संदर्भ दिया जाता है, संकलित कोड को पहले जांच करनी चाहिए कि dict कुछ भी बराबर नहीं है।

लेकिन यह मेरे लिए होता है कि संकलित कोड वैसे भी करता है। किसी भी समय जब आप किसी ऑब्जेक्ट संदर्भ का उपयोग करने का प्रयास करते हैं तो आपको एक त्रुटि मिलेगी जो Nothing है।

तो, विज्ञान के लिए श्रद्धांजलि में, मैंने कुछ परीक्षण चलाए। और परिणाम बताते हैं कि दोनों दृष्टिकोणों के बीच कोई प्रदर्शन अंतर नहीं है। (Excel 2007 पर चलाने के लिए)

कॉल 100,000 बार "बनाने के शब्दकोश & 2 आइटम जोड़ने"।

  • स्पष्ट: 16,891ms/ऑटो: 16,797ms (ऑटो 94ms तेज)
  • स्पष्ट: 16,797ms/ऑटो: 16,781ms (ऑटो 16ms तेजी से)

परीक्षण कॉल के आदेश रिवर्स :

  • ऑटो: 16,766ms/स्पष्ट: 16,812ms (ऑटो 46ms तेज)
  • ऑटो: 16,828ms/स्पष्ट: 16,813ms (स्पष्ट 15ms तेज)

कॉल 100,000 बार "बनाने के शब्दकोश & 6 आइटम जोड़ने"।

  • ऑटो: 17,437ms/स्पष्ट: 17,407ms (स्पष्ट 30ms तेज)
  • ऑटो: 17,343ms/स्पष्ट: 17,360ms (ऑटो 17ms तेजी से)

शब्दकोश बनाएँ और 100,000 जोड़ने आइटम नहीं है।

  • ऑटो: 391ms/स्पष्ट: 391ms (एक ही)

शब्दकोश बनाएं और 1,000,000 आइटम जोड़ने।

  • ऑटो: 57,609ms/स्पष्ट: 58,172ms (ऑटो 563ms तेज)
  • स्पष्ट: 57,343ms/ऑटो: 57,422ms (स्पष्ट 79ms तेजी से)

मुझे लगता है कि इंगित करने के लिए कुछ भी नहीं देखना ऑटो-इंस्टेंटेशन स्पष्ट तत्कालता के लिए एक खराब प्रदर्शन संबंध है। (स्पष्ट होने के लिए, अन्य कारणों से, मैं ऑटो-इंस्टेंटेशन से बचूंगा लेकिन मुझे यहां प्रदर्शन कोण में दिलचस्पी है।)

तो क्या यह एक मिथक है?

अद्यतन

मुझे बाहर रखना क्यों प्रदर्शन तर्क मेरे लिए कोई मतलब नहीं है करते हैं। कहा जाता है कि

x.Add("Key", "Item") 
एक स्वत: instantiated वस्तु में

निम्नलिखित के बराबर है:

If x is Nothing then 
    Set x = New Dictionary 
End If 
x.Add("Key", "Item") 

जो इसे पसंद "भयावह भूमि के ऊपर" देखो तुम समय की इस हजारों बुला रहे हैं बनाता है। लेकिन स्पष्ट इन्स्टेन्शियशन मामले में, यह वास्तव में कोड की संकलित संस्करण में उत्पन्न तर्क के रूप है:

If x is Nothing Then 
    Err.Raise "Object variable not set..." 
End If 
x.Add("Key", "Item") 

यह जरूरी है कि ऑटो का पालन नहीं करता है कि क्या वहाँ था कि मैं क्यों पूछ रहा हूँ, अब है इस के लिए कोई सच है। मुझे आश्चर्य है कि मैंने कई अनचाहे प्रदर्शन मिथकों में से एक को पहचाना है।

+0

यह वास्तव में केवल अलग-अलग "कुछ भी नहीं" अर्थशास्त्र है जो 'Dim/Set' के अलावा थोड़ा 'As' सेट करता है। जैसा कि आप कहते हैं कि रनटाइम प्रकार की जांच से जुड़े तथाकथित ओवरहेड को अप्रासंगिक माना जाता है कि जब तक कि चेक किए गए ऑटो-इंस्टॉस्ड ऑब्जेक्ट वास्तव में * * कुछ भी नहीं 'है, तो यह' Dim/Set' संदर्भ 'से अधिक नहीं होता है। –

+0

@ एलेक्स के, इस उम्र के पुराने प्रदर्शन दिशानिर्देश कहते हैं कि * प्रत्येक * वैरिएबल के संदर्भ में ऑटो केस में "यदि एक्स कुछ भी नहीं है" का आह्वान करेगा, जो एक मंद/सेट चर नहीं होगा। इसलिए जब आप घोषणापत्र के बाद ऑब्जेक्ट तक पहुंचते हैं तो घोषणा प्रदर्शन के बजाए प्रदर्शन प्रदर्शन होने पर आपको परीक्षण करना पड़ता है। –

+0

@ जेपी सच नहीं है- मैंने इसे एक और SO प्रश्न के बाद गुगल किया, आज मैं देख रहा था। उदाहरण: http://www.cpearson.com/excel/classes.aspx एक और उदाहरण: http://www.bettersolutions.com/vba/VUA113/LI912711911.htm –

उत्तर

5

मैं जानता हूँ कि वहाँ पर पवित्र तरीका है अगर यह ठीक है या के रूप में नए धुंधला करने के लिए नहीं है, लेकिन मैं इसे खराब प्रदर्शन उत्पन्न करने के लिए कहा जा रहा है कभी नहीं सुना है। संक्षिप्त उत्तर वास्तव में नहीं है। हां यह आपके कोड को अनैतिक जांच के साथ कूड़ा करता है यह देखने के लिए कि क्या यह कुछ भी नहीं है, लेकिन आपको आज की मशीनों के लिए गति अंतर दिखाई नहीं देगा। यह कहने जैसा है "10000 से अधिक अक्षरों को लूप करने के लिए 10001 से तेज है। किसी भी अंतर को देखने के लिए, आपको लाखों और लाखों लाखों जैसे उच्चतर शब्दों में अपने परीक्षणों को लूप करना होगा।

कहा जा रहा है कि डिम नई है । पर नहीं बल्कि प्रदर्शन कारणों से

  • आप जब यह प्रारंभ है
  • आप अगर एक वस्तु कुछ भी नहीं
  • स्पीड अंतर है या नहीं की जाँच करने की क्षमता खो नियंत्रित करने की क्षमता खो देते हैं, इसके साथ कूड़े अपने कोड करता है unnessesary जांच

दी अगर आप सिर्फ कुछ कार्यपत्रक सामान को स्वचालित या डेटा में हेरफेर करने के लिए VBA का उपयोग कर रहे हैं, तो आप शायद इन के बारे में परवाह नहीं है, लेकिन जैसे ही आप और अधिक परिष्कृत कोड को देखो, अगर एक वस्तु कुछ भी नहीं है और है परीक्षण करने के लिए क्षमता खो प्रारंभ होने पर इसे नियंत्रित नहीं करना बहुत बड़ा है और अप्रत्याशित व्यवहार उत्पन्न कर सकता है, न कि बट में दर्द का परीक्षण करने के लिए। कोड की कुछ पंक्तियों को बचाने के लिए यह सब कुछ है।

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

+0

मैं मानता हूं कि इसे प्रारंभ होने पर नियंत्रित करने की क्षमता खो जाती है; और मुझे लगता है कि यह एक और गंभीर समस्या है कि वस्तु को कुछ भी करने के लिए व्यावहारिक रूप से असंभव नहीं है। लेकिन सवाल "अनावश्यक जांच" के बारे में है - क्या यह सच है? आखिरकार, यदि मैं डिम एक्स को डिक्शनरी के रूप में लिखता हूं तो x.Add (1, "m") - मुझे एक त्रुटि मिल जाएगी जिसमें "ऑब्जेक्ट वेरिएबल सेट नहीं है" जिसका अर्थ है संकलित वीबीए वैसे भी इसे जांच रहा है। –

+0

रनटाइम के दौरान संकलन और जांच के दौरान जांच बहुत अलग है। मेरा विश्वास करो, संकलन समय पर जांच करना एक अच्छी बात है और इसे रनटाइम पर छोड़ना नहीं है। :) और जब कोई त्रुटि फेंकती है, तो यह जांच नहीं होती है और महसूस किया जाता है कि यह ऐसा नहीं कर सका, यह है कि यह ऐसा करने का प्रयास करता है जो वह नहीं कर सका। – aevanko

+0

+1 "यह जांचने की क्षमता खो रहा है कि कोई ऑब्जेक्ट कुछ नहीं है और इसे प्रारंभ होने पर नियंत्रित नहीं किया जा रहा है" - एक प्रोग्रामर नियंत्रण में होना चाहिए, कोड नहीं। जब कोई चर घोषित किया जाता है तो एक अंतर्निहित "कुछ भी नहीं" जांच करने से प्रदर्शन लाभ इस विचार से बहुत अधिक है। – JimmyPena

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