2010-08-13 13 views
9

स्ट्रिंग के सबस्ट्रिंग लेना एक बहुत ही सामान्य स्ट्रिंग मैनिपुलेशन ऑपरेशन है, लेकिन मैंने सुना है कि जावा और .NET प्लेटफ़ॉर्म के बीच प्रदर्शन/कार्यान्वयन में काफी अंतर हो सकते हैं। विशेष रूप से मैंने सुना है कि जावा में, java.lang.Stringsubstring के लिए निरंतर समय आपरेशन प्रदान करता है, लेकिन नेट में, System.Stringरैखिक प्रदर्शन Substring प्रदान करता है।.NET और Java

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

+1

इसका परीक्षण करने के लिए अपने स्वयं के माइक्रो बेंचमार्क क्यों न चलाएं ? क्या आप उन स्रोतों से लिंक कर सकते हैं जो कहते हैं कि इसमें "खराब" प्रदर्शन है? – Oded

+0

@ ओडेड: स्रोत डैनी चेन की टिप्पणी यहां है http://stackoverflow.com/questions/3474254/how-to-make-a- फर्स्ट-letter-capital-in-c/3474263#3474263; ईमानदारी से मैं आश्चर्यचकित हूं कि 'सबस्ट्रिंग'' ओ (1) 'समय-और-अंतरिक्ष संचालन नहीं है (जैसे जावा), लेकिन मैं उसे संदेह का लाभ दे रहा हूं क्योंकि मुझे .NET नहीं पता है। – polygenelubricants

+1

इसका मतलब क्या है "खराब प्रदर्शन"? क्या सापेक्ष है? उदाहरण के लिए सी ++ की तुलना में .NET का भी खराब प्रदर्शन होता है। क्या हमें इसके कारण .NET ड्रॉप करना चाहिए? –

उत्तर

11

नेट में है Substring हे (एन) बल्कि जावा के हे (1) से अधिक है। ऐसा इसलिए है क्योंकि .NET में, स्ट्रिंग ऑब्जेक्ट में सभी वास्तविक वर्ण डेटा शामिल हैं - इसलिए एक सबस्ट्रिंग लेने से नए सबस्ट्रिंग के भीतर सभी डेटा कॉपी करना शामिल होता है। जावा में, substring एक अलग प्रारंभिक अनुक्रमणिका और लंबाई के साथ, मूल चार सरणी का जिक्र करते हुए एक नई वस्तु बना सकता है।

  • नेट का दृष्टिकोण, बेहतर कैश जुटना है बनाता है कम वस्तुओं , और स्थिति है जहाँ एक छोटी सी-स्ट्रिंग एक बहुत बड़ी char[] जा रहा कचरा एकत्र होने से बचाता है से बचा जाता है:

    वहाँ पेशेवरों और प्रत्येक दृष्टिकोण के विपक्ष हैं । मुझे विश्वास है कि कुछ मामलों में यह आंतरिक रूप से इंटरऑप को भी बहुत आसान बना सकता है।

  • जावा का दृष्टिकोण बहुत ही कुशल सबस्ट्रिंग लेने बनाता है, और शायद कुछ अन्य कार्यों भी

मेरे strings article में थोड़ा और विस्तार है।

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


संयोग से, इस string बहुत ही खास बना देता है - यह केवल गैर सरणी प्रकार चुनें जिसकी स्मृति पदचिह्न ही CLR भीतर उदाहरण से भिन्न होता है है।

छोटे तारों के लिए, यह एक बड़ी जीत है। यह इतना बुरा है कि एक ऑब्जेक्ट के सभी ओवरहेड हैं, लेकिन जब एक अतिरिक्त सरणी भी शामिल होती है, तो एकल-वर्ण स्ट्रिंग जावा में लगभग 36 बाइट्स ले सकती है। (यह एक "उंगली-इन-द-एयर" नंबर है - मुझे सटीक ऑब्जेक्ट ओवरहेड्स याद नहीं है। यह आपके द्वारा उपयोग किए जा रहे वीएम पर भी निर्भर करेगा।)

2

परावर्तक का उपयोग करते हुए इस तुम क्या सबस्ट्रिंग से मिलता है (Int32, Int32)

[SecuritySafeCritical, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
public string Substring(int startIndex, int length) 
{ 
    return this.InternalSubStringWithChecks(startIndex, length, false); 
} 

अगर आप आखिरी कॉल के अंदर जा रहा पर रखने है एक

है
internal static unsafe void wstrcpy(char* dmem, char* smem, int charCount) 

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

0

यह वास्तव में आपके वर्कलोड पर निर्भर करता है। यदि आप लूपिंग कर रहे हैं और बहुत सारे सबस्ट्रिंग कॉल कर रहे हैं, तो आपको कोई समस्या हो सकती है। एसओ पोस्ट के लिए आप जिक्र कर रहे हैं, मुझे संदेह है कि यह कभी भी एक समस्या होगी। हालांकि, उस दृष्टिकोण के साथ, आप हमेशा "एक हजार पेपर कटौती की मौत" की स्थिति में उड़ सकते हैं। में ऐसा आप का उल्लेख पोस्ट, हम निम्नलिखित है:

String after = before.Substring(0, 1).ToUpper() + before.Substring(1); 

संकलक मान लिया जाये कि कुछ पागल अनुकूलन नहीं करता है, यह कम से कम चार नए तार (2 Substring कॉल, एक ToUpper कॉल, और पैदा करेगा संयोजन)। सबस्ट्रिंग ठीक उसी तरह कार्यान्वित किया जाता है जैसा आप अपेक्षा करते हैं (स्ट्रिंग कॉपी), लेकिन उपरोक्त आवंटित तारों में से तीन जल्द ही कचरा बन जाएंगे। इसमें से बहुत कुछ करने से अनावश्यक स्मृति दबाव पैदा होगा। मैं "अनावश्यक" कहता हूं क्योंकि आप शायद थोड़ा और अधिक निवेश के साथ एक और अधिक किफायती समाधान के साथ आ सकते हैं।

अंत में, प्रोफाइलर, अपने सबसे अच्छे दोस्त :)