2009-04-04 17 views

cevap

26

Ben çoğunlukla parçacığının geçerli kültür getirilirken düşünüyorum.

Eğer String.StartsWith şeklini kullanabilmek için Marc'ın testini değiştirirseniz

:

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); 

bunu çok daha yakın geliyor.

s1.StartsWith(s2, StringComparison.Ordinal) kullanırsanız, CompareInfo.IsPrefix'u kullanmadan çok daha hızlıdır (tabiki CompareInfo'a bağlı olarak). Benim kutusunda sonuçları (değil bilimsel olarak) şunlardır:

  • s1.StartsWith (s2): 6914ms
  • s1.StartsWith (s2, yalancı, kültür): 5568ms
  • compare.IsPrefix (s1, s2): 5200ms
  • s1.StartsWith (s2, StringComparison.Ordinal): 1393ms

gerçekten sadece oldukça ucuz olan her noktada 16 bitlik tamsayılar karşılaştırarak çünkü Açıkçası bu. ,'un kültüre duyarlı kontrol yapmasını istemiyorsanız, ve performansı özellikle sizin için önemlidir, bu benim kullanacağım aşırı yüktür.

5

Başlatmalar IsPrefix'i dahili olarak başlatır. IsPrefix'i çağırmadan önce kültür bilgilerini atar.

5

İyi soru; Bir test için, alıyorum:

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

Testi kulesi:

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 kaynağını gözden geçirin. Aslında, bazı durumlarda, StartsWith'i kullanması ve birkaç tane daha işlem yapması nedeniyle StartsWith'dan daha yavaş olacak.

[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); 
    } 
İlgili konular