2010-08-02 12 views
11

यह है:लूप के अंदर/बाहर एक चर घोषित करने से प्रदर्शन में परिवर्तन होगा?

foreach(Type item in myCollection) 
{ 
    StringBuilder sb = new StringBuilder(); 
} 

बहुत धीमी है:

StringBuilder sb = new StringBuilder(); 

foreach(Type item in myCollection) 
{ 
    sb = new StringBuilder(); 
} 

दूसरे शब्दों में, क्या यह वास्तव में मायने रखता है कि मैं अपना StringBuilder कहां घोषित करता हूं?

+3

http://stackoverflow.com/questions/2447475/best-practice-for-creating-objects-used-in-for-foreach-loops –

+1

की तरह एक असंबंधित त्रुटि यह है कि दूसरा संस्करण शून्य करने के लिए प्रारंभ करना चाहिए अतिरिक्त आवंटन से बचने के लिए। –

उत्तर

12

आप शायद, कुछ प्रदर्शन हासिल कर सकता है अगर आप इस बारे में:

StringBuilder sb = new StringBuilder(); 
foreach(Type item in myCollection) 
{ 
    sb.Length = 0; 
} 

तो तुम सिर्फ एक बार StringBuilder का दृष्टांत और पाश में आकार है, जो एक नई वस्तु instantiating की तुलना में थोड़ा तेजी से होना चाहिए पुनर्स्थापित करने के लिए है ।

+0

+1 अच्छा बिंदु ... – SLaks

+1

+1: निर्मित स्ट्रिंग के आकार और एसबी में परिणामी आंतरिक बफर के आधार पर, यह एक मापनीय अंतर बना सकता है। – Alex

+2

यह हो सकता है, लेकिन यह भी नहीं हो सकता है। जब आप 'ToString' कहते हैं, तो यह बफर की प्रतिलिपि बनाता है। मैं यह मानता हूं कि यह सोचने का कोई कारण था कि यह प्रदर्शन-संवेदनशील था। –

14

नहीं, इससे प्रदर्शन की बात नहीं होगी, जहां आप इसे घोषित करते हैं।

सामान्य कोड-सफाई के लिए, आपको इसे आंतरिक-अधिकांश दायरे में घोषित करना चाहिए जिसका उपयोग किया जाता है - यानी। आपका पहला उदाहरण

+1

यह वैसे भी उसी आईएल में संकलित होना चाहिए जो मुझे लगता है।खैर, अगर वह दो बार एसबी शुरू नहीं कर रहा था। –

+1

अगर मैं गलत हूं, तो मुझे सही करें, लेकिन यदि आप इसे लूप के अंदर घोषित करते हैं तो क्या यह इसके बाहर अनुपयोगी नहीं होगा (अविकसित)? – NullUserException

+3

@NullUserException हाँ, आप सही हैं। लेकिन अगर आपको लूप के बाहर इसकी आवश्यकता नहीं है, तो इसे लूप के अंदर घोषित करने के लिए स्पष्ट है – sloth

2

दूसरे उदाहरण में आप स्ट्रिंगबिल्डर का एक अतिरिक्त उदाहरण बना रहे हैं। इसके अलावा वे दोनों समान हैं, इसलिए प्रदर्शन समस्या लापरवाह है।

+0

यह मेरी राय में प्रश्न का एक टिप्पणी होना चाहिए। – Shaihi

+0

@Shaihi - क्यों? w69rdy सवाल का जवाब दे रहा है। – mphair

1

आपके विशिष्ट मामले में प्रदर्शन अंतर स्पष्ट रूप से इंगित करने के लिए यहां पर्याप्त कोड नहीं है। ऐसा कहा जाता है कि, इस बनाम के बाहर एक लूप के अंदर एक संदर्भ चर घोषित करने के बीच अंतर ज्यादातर मामलों के लिए मामूली है।

1

आपके दो कोड नमूने के बीच प्रभावी अंतर यह है कि दूसरा पहले की तुलना में StringBuilder का 1 और उदाहरण आवंटित करेगा। आपके शेष आवेदन की तुलना में इसका प्रदर्शन प्रभाव अनिवार्य रूप से कुछ भी नहीं है।

0

चेक करने का सबसे अच्छा तरीका लूप में दोनों विधियों को आजमाकर, लगभग 100,000 प्रत्येक कोशिश कर रहा है। प्रत्येक 100,000 पुनरावृत्तियों को लेने और उनकी तुलना करने की मात्रा को मापें। मुझे नहीं लगता कि इसमें बहुत अंतर है। लेकिन हालांकि, एक छोटा सा अंतर है। पहले उदाहरण में पुनरावृत्तियों की संख्या के रूप में कई चर होंगे। दूसरे उदाहरण में सिर्फ एक चर है। कंपाइलर यहां कुछ अनुकूलन करने के लिए पर्याप्त स्मार्ट है, इसलिए आपको गति सुधार दिखाई नहीं देगा। हालांकि, यदि आप दोबारा लूप के बाहर होने के बाद लूप के अंदर उत्पन्न अंतिम वस्तु का उपयोग नहीं करना चाहते हैं, तो पहला समाधान बेहतर होगा। दूसरे समाधान में, कचरा कलेक्टर बनाई गई अंतिम वस्तु को मुक्त करने में कुछ समय लगेगा। पहले उदाहरण में, कचरा कलेक्टर ऑब्जेक्ट को मुक्त करने में थोड़ा तेज़ होगा। यह शेष कोड पर निर्भर करता है लेकिन यदि आप इस स्ट्रिंगबिल्डर ऑब्जेक्ट में बहुत अधिक डेटा संग्रहीत करते हैं तो दूसरा उदाहरण इस स्मृति को बहुत अधिक समय तक रख सकता है, इस प्रकार लूप छोड़ने के बाद आपके कोड के प्रदर्शन को कम कर देता है!
फिर, यदि ऑब्जेक्ट्स 100 केबी खाती हैं और आपके मशीन में 16 जीबी है, तो कोई भी परवाह नहीं करता है ... कचरा कलेक्टर अंततः इसे फिर से मुक्त कर देगा, शायद जैसे ही आप इस लूप वाले विधि को छोड़ दें।

0

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

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