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를 사용하고 더 많은 작업을 수행하기 때문에 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); 
    } 
관련 문제