2009-04-04 6 views

उत्तर

26

मुझे लगता है कि यह ज्यादातर धागा की मौजूदा संस्कृति को लाते समय है।

आप String.StartsWith के लिए इस प्रपत्र का उपयोग करने के मार्क के परीक्षण को बदलते हैं:

Stopwatch watch = Stopwatch.StartNew(); 
    CultureInfo cc = CultureInfo.CurrentCulture; 
    for (int i = 0; i < LOOP; i++) 
    { 
     if (s1.StartsWith(s2, false, cc)) chk++; 
    } 
    watch.Stop(); 
    Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk); 

यह एक बहुत करीब आता है।

यदि आप s1.StartsWith(s2, StringComparison.Ordinal) का उपयोग करते हैं तो यह CompareInfo.IsPrefix का उपयोग करने से बहुत तेज़ है (निश्चित रूप से CompareInfo के आधार पर)। मेरी बॉक्स पर परिणाम (वैज्ञानिक रूप से नहीं) कर रहे हैं:

  • s1.StartsWith (s2): 6914ms
  • s1.StartsWith (s2, झूठे, संस्कृति): 5568ms
  • compare.IsPrefix (S1, S2): 5200ms
  • s1.StartsWith (s2, StringComparison.Ordinal): 1393ms

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

5

स्टार्ट्स आंतरिक रूप से IsPrefix को कॉल करता है। यह IsPrefix को कॉल करने से पहले संस्कृति की जानकारी असाइन करता है।

5

अच्छा सवाल; एक परीक्षण के लिए, मैं मिलता है:

9156ms; chk: 50000000 
6887ms; chk: 50000000 

टेस्ट रिग:

using System; 
using System.Diagnostics; 
using System.Globalization;  

class Program 
{ 
    static void Main() 
    { 
     string s1 = "abcdefghijklmnopqrstuvwxyz", s2 = "abcdefg"; 

     const int LOOP = 50000000; 
     int chk = 0; 
     Stopwatch watch = Stopwatch.StartNew(); 
     for (int i = 0; i < LOOP; i++) 
     { 
      if (s1.StartsWith(s2)) chk++; 
     } 
     watch.Stop(); 
     Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk); 

     chk = 0; 
     watch = Stopwatch.StartNew(); 

     CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo; 
     for (int i = 0; i < LOOP; i++) 
     { 
      if (ci.IsPrefix(s1, s2)) chk++; 
     } 
     watch.Stop(); 
     Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk); 
    } 
} 
0

IsPrefix के स्रोत को देखें। बात यह है कि - कुछ मामलों में, यह StartsWith से धीमा होने वाला है क्योंकि यह वास्तव में स्टार्ट्सविथ का उपयोग करता है और कुछ और संचालन करता है।

[System.Security.SecuritySafeCritical] // auto-generated 
    public unsafe virtual bool IsPrefix(String source, String prefix, CompareOptions options) 
    { 
     if (source == null || prefix == null) { 
      throw new ArgumentNullException((source == null ? "source" : "prefix"), 
       Environment.GetResourceString("ArgumentNull_String")); 
     } 
     Contract.EndContractBlock(); 
     int prefixLen = prefix.Length; 

     if (prefixLen == 0) 
     { 
      return (true); 
     } 

     if (options == CompareOptions.OrdinalIgnoreCase) 
     { 
      return source.StartsWith(prefix, StringComparison.OrdinalIgnoreCase); 
     } 

     if (options == CompareOptions.Ordinal) 
     { 
      return source.StartsWith(prefix, StringComparison.Ordinal); 
     } 

     if ((options & ValidIndexMaskOffFlags) != 0) { 
      throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options"); 
     } 


     // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to 
     // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString. 

     return (InternalFindNLSStringEx(
        m_dataHandle, m_handleOrigin, m_sortName, 
        GetNativeCompareFlags(options) | Win32Native.FIND_STARTSWITH | ((source.IsAscii() && prefix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0), 
        source, source.Length, 0, prefix, prefix.Length) > -1); 
    } 
संबंधित मुद्दे

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