String.Contains () String.IndexOf () से अधिक तेज़ है?


111

मेरे पास लगभग 2000 वर्णों का एक स्ट्रिंग बफ़र है और बफ़र की जाँच करने की आवश्यकता है यदि इसमें एक विशिष्ट स्ट्रिंग है।
हर webrequest के लिए ASP.NET 2.0 वेबऐप में चेक करेगा।

क्या किसी को पता है कि अगर String.Contains विधि प्रदर्शन की तुलना में बेहतर String.IndexOf विधि ?

    // 2000 characters in s1, search token in s2
    string s1 = "Many characters. The quick brown fox jumps over the lazy dog"; 
    string s2 = "fox";
    bool b;
    b = s1.Contains(s2);
    int i;
    i = s1.IndexOf(s2);

मजेदार तथ्य


14
यदि आपको प्रति वेब अनुरोध में एक अरब बार ऐसा करने की आवश्यकता है, तो मैं इस तरह से सामान देखना शुरू करूंगा। किसी भी अन्य मामले में, मैं परेशान नहीं होता, क्योंकि या तो विधि में बिताया गया समय सबसे पहले HTTP अनुरोध प्राप्त करने की तुलना में अविश्वसनीय रूप से महत्वहीन होगा।
mookid8000

2
अनुकूलन की कुंजी में से एक को संभालने के बजाय परीक्षण करना है, क्योंकि यह बहुत सारे कारकों पर निर्भर कर सकता है जैसे .NET संस्करण, ऑपरेटिंग सिस्टम, हार्डवेयर, इनपुट में भिन्नता, आदि बहुत से मामलों में दूसरों द्वारा किए गए परीक्षा परिणाम। आपके सिस्टम पर बहुत भिन्न हो सकते हैं।
स्लैई

जवाबों:


174

Containsकॉल IndexOf:

public bool Contains(string value)
{
    return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}

जो कॉल करता है CompareInfo.IndexOf, जो अंततः सीएलआर कार्यान्वयन का उपयोग करता है।

यदि आप यह देखना चाहते हैं कि CLR में तार की तुलना कैसे की जाती है तो यह आपको दिखाएगा ( CaseInsensitiveCompHelper के लिए देखें )।

IndexOf(string)कोई विकल्प नहीं है और Contains()एक साधारण तुलना का उपयोग करता है (एक बाइट-बाइट तुलना, स्मार्ट तुलना करने की कोशिश करने के बजाय, उदाहरण के लिए, ई के साथ ई)।

तो IndexOfथोड़ा और तेजी से (सिद्धांत में) होगा जैसा कि IndexOfकर्नेल 32.dll (रिफ्लेक्टर की शक्ति!) से FindNLSString का उपयोग करके सीधे स्ट्रिंग खोज में जाता है।

.NET 4.0 के लिए अपडेट किया गया - IndexOf अब साधारण तुलना का उपयोग नहीं करता है और इसलिए इसमें शामिल होने की प्रक्रिया तेज हो सकती है। नीचे टिप्पणी देखें।


3
यह उत्तर कहीं भी सही नहीं है, बस यहां एक नज़र डालते हैं stackoverflow.com/posts/498880/revisions स्पष्टीकरण के लिए
pzaj

55
मेरा उत्तर 7 साल पुराना है और .NET 2 ढांचे पर आधारित है। संस्करण 4 IndexOf()वास्तव में उपयोग करता है StringComparison.CurrentCultureऔर Contains()उपयोग करता है StringComparison.Ordinalजो तेज होगा। लेकिन वास्तव में हम जिस गति अंतर के बारे में बात कर रहे हैं वह मिनट है - बिंदु एक दूसरे को कॉल करता है, और यदि आपको सूचकांक की आवश्यकता नहीं है, तो कॉन्टेन्स अधिक पठनीय है। दूसरे शब्दों में इसके बारे में चिंता न करें।
क्रिस एस

21

शायद, यह बिल्कुल भी मायने नहीं रखेगा। कोडिंग हॉरर पर इस पोस्ट को पढ़ें;): http://www.codinghorror.com/blog/archives/001218.html


4
बॉस को चूसते हुए हम हैं ...? : D आप एक HTTP अनुरोध को पूरा करने में लगने वाले समय की तुलना में सही हैं, फिर भी, एक बार, यह महत्वपूर्ण नहीं है।
फव्ल

एक बहुत ही मनोरंजक पढ़ा, लेकिन यह मुझे उसकी प्रारंभिक शिकायत को परेशान करता है स्मृति उपयोग, फिर वह केवल तार को संयोजित करने के विभिन्न तरीकों के साथ बिताए समय के लिए परीक्षण करता है।
sab669

11

Contes (s2) IndexOf (s2) की तुलना में कई गुना (मेरे कंप्यूटर में 10 गुना) तेजी से होता है क्योंकि Contains StringComparison.Ordinal का उपयोग करता है जो कि उस संवेदी संवेदनशील खोज की तुलना में अधिक तेज़ है जो IndexOf डिफ़ॉल्ट रूप से करता है (लेकिन जो कि innet 4.0 http बदल सकता है : //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx )।

मेरी परीक्षाओं में IndexOf (s2, StringComparison.Ordinal)> = 0 के समान ही प्रदर्शन है, लेकिन यह छोटा है और आपकी मंशा को स्पष्ट करता है।


2
.NET 4.0 में परिवर्तन जाहिरा तौर पर आरटीएम जाने से पहले वापस कर दिए गए थे, इसलिए मैं उस लेख पर बहुत अधिक blogs.msdn.com/bclteam/archive/2008/11/04/…
स्टीफन कैनेडी

7

मैं एक वास्तविक मामला चला रहा हूं (एक सिंथेटिक बेंचमार्क के विपरीत)

 if("=,<=,=>,<>,<,>,!=,==,".IndexOf(tmps)>=0) {

बनाम

 if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {

यह मेरी प्रणाली का एक महत्वपूर्ण हिस्सा है और इसे 131,953 बार (धन्यवाद डॉट्रेस) निष्पादित किया गया है।

हालांकि चौंकाने वाला आश्चर्य , परिणाम विपरीत है जो अपेक्षित है

  • IndexOf 533ms।
  • 266ms शामिल हैं।

: - /

शुद्ध रूपरेखा 4.0 (13-02-2012 तक अद्यतन)


1
क्योंकि INTबहुत बड़ा है BOOL, और IndexOf>=0एक और कदम का कारण है
एरिक यिन

3
आप ringStringComparison.Ordinal Dav
Davi Fiamenghi

6

Reflector का उपयोग करके, आप देख सकते हैं, कि IndexOf का उपयोग करके Contains लागू किया गया है। यहाँ कार्यान्वयन है।

public bool Contains(string value)
{
   return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}

इसलिए कॉन्टेक्ट्स इंडेक्सऑफ को सीधे कॉल करने की तुलना में थोड़ा सा धीमा है, लेकिन मुझे संदेह है कि वास्तविक प्रदर्शन के लिए इसका कोई महत्व होगा।


1
हां, लेकिन एक बूल के रूप में इंडेक्स का उपयोग करने के लिए, उसे फ़ंक्शन के बाहर तुलना करना होगा। यह सबसे अधिक संभावना है कि कंटेन्स के रूप में एक ही परिणाम देगा, है ना?
गोंजालो कुरो

1
शायद, लेकिन आप एक विधि कॉल को सेव करते हैं (जब तक कि यह इनलेट नहीं किया जा सकता है)। जैसा कि मैंने कहा, यह शायद कभी महत्वपूर्ण नहीं होगा।
ब्रायन रासमुसेन

6

यदि आप वास्तव में अपने कोड को माइक्रो ऑप्टिमाइज़ करना चाहते हैं तो आपका सबसे अच्छा तरीका हमेशा बेंचमार्किंग है।

.Net फ्रेमवर्क का एक उत्कृष्ट स्टॉपवॉच कार्यान्वयन है - System.Diagnostics.Stopwatch


यह सबसे अच्छा है, लेकिन यदि आप एक त्वरित दृष्टिकोण चाहते हैं तो बस डिबग सत्र में पॉज़ बटन दबाएं। लगभग 50% समय में सबसे धीमी गति से कोड नियंत्रण रुकने की संभावना है ।
जेरेमी थॉम्पसन

4

थोड़ा पढ़ने से, यह प्रतीत होता है कि हुड के नीचे स्ट्रिंग.कंठों की विधि बस String.IndexOf को कॉल करती है। अंतर String.Contains एक बूलियन देता है, जबकि String.IndexOf (-1) के साथ पूर्णांक देता है यह दर्शाता है कि प्रतिस्थापन नहीं मिला।

मैं 100,000 या तो पुनरावृत्तियों के साथ थोड़ा परीक्षण लिखने और खुद को देखने का सुझाव दूंगा। अगर मुझे लगता था, तो मैं कहूंगा कि IndexOf थोड़ा तेज हो सकता है, लेकिन जैसा मैंने कहा कि यह सिर्फ एक अनुमान है।

जेफ एटवुड का अपने ब्लॉग पर स्ट्रिंग्स पर एक अच्छा लेख है । यह संगति के बारे में अधिक है, लेकिन फिर भी मददगार हो सकता है।


3

बस इस के अपडेट के रूप में मैं कुछ परीक्षण कर रहा हूं और आपके इनपुट स्ट्रिंग प्रदान करना काफी बड़ा है तो समानांतर रेगेक्स सबसे तेज सी # विधि है जो मैंने पाया है (बशर्ते आपके पास एक से अधिक कोर हैं जो मैं कल्पना करता हूं)

उदाहरण के लिए मैचों की कुल राशि प्राप्त करना -

needles.AsParallel ( ).Sum ( l => Regex.IsMatch ( haystack , Regex.Escape ( l ) ) ? 1 : 0 );

उम्मीद है की यह मदद करेगा!


1
एक अलग थ्रेड पर हाय फील इसे tomasp.net/articles/ahocorasick.aspx के एक संस्करण से अपडेट किया गया है, जो आपके कीवर्ड (सुइयों) को प्रदान नहीं करता है, बहुत तेज है।
गैरी

2

एक बेंचमार्क लाइब्रेरी का उपयोग करें, इसे मापने के लिए जॉन स्कीट से हाल ही की तरह ।

कैविट एमप्टर

जैसा कि सभी (माइक्रो-) प्रदर्शन प्रश्न हैं, यह आपके द्वारा उपयोग किए जा रहे सॉफ़्टवेयर के संस्करणों पर निर्भर करता है, डेटा का विवरण और कॉल के आसपास का कोड।

सभी (माइक्रो-) प्रदर्शन सवालों के रूप में, पहला कदम एक चलने वाला संस्करण प्राप्त करना होगा जो आसानी से बनाए रखने योग्य है। फिर बेंचमार्किंग, प्रोफाइलिंग और ट्यूनिंग को अनुमान लगाने के बजाय मापा बाधाओं पर लागू किया जा सकता है।


हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं।
माइक स्टॉकडेल

लिंक की गई लाइब्रेरी केवल कई में से एक है, और उत्तर का मुख्य जोर नहीं है। मुझे नहीं लगता कि पुस्तकालयों के स्रोत या विवरण को पोस्ट करने से उत्तर, इस साइट या दुनिया में सुधार होगा।
डेविड श्मिट

3
-1; सवाल था "क्या कोई जानता है कि String.Contains विधि String.IndexOf विधि से बेहतर प्रदर्शन करती है?" - आपका उत्तर "एक बेंचमार्क लाइब्रेरी का उपयोग करें" है, जिसका मूल अर्थ है "मुझे नहीं पता, यह स्वयं करें", "यह निर्भर करता है", जिसका अर्थ है "मुझे नहीं पता", और "एक रनिंग संस्करण और प्रोफ़ाइल प्राप्त करें"। , जिसका अर्थ है "मैं नहीं जानता, यह स्वयं करो"। यह 'ख़तरा' नहीं है - कृपया पूछे गए प्रश्न का उत्तर प्रदान करें , न कि कैसे-कैसे विचार - उनकी जगह टिप्पणियों में है

-7

अभी भी इसे पढ़ने वाले किसी भी व्यक्ति के लिए, indexOf () संभवतः अधिकांश एंटरप्राइज़ सिस्टम पर बेहतर प्रदर्शन करेगा, क्योंकि इसमें () IE के साथ संगत नहीं है!


12
नई OutOfScopeException () फेंकें;
राफेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.