C# (.NET)의 StartsWith 기능이 IsPrefix보다 상당히 느린 이유를 아는 사람이 있습니까?왜 함수가 C#의 Startswith보다 더 빠릅니까?
15
A
답변
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);
}
관련 문제
- 1. 왜 순수 함수가 Mathematica 코드에서 더 빠릅니까?
- 2. 정적 기능이 더 빠릅니까?
- 3. 버퍼와 문자열 속도 : 왜 문자열이 더 빠릅니까?
- 4. 공개 필드가 속성보다 왜 더 빠릅니까?
- 5. 왜 코어보다 스레드 수가 더 빠릅니까?
- 6. 왜 PathPing이 Tracert보다 빠릅니까?
- 7. PHP Dom 문서 html이 빠르거나 preg_match_all 함수가 더 빠릅니까?
- 8. 왜 fwrite libc 함수가 syscall write 함수보다 빠릅니까?
- 9. 어느 것이 더 빠릅니까?
- 10. 어느 것이 더 빠릅니까?
- 11. 어떤 선택자가 더 빠릅니까?
- 12. 왜 LIKE가 =보다 빠릅니까?
- 13. 왜 Vim에서 \ % (\)가 \ (\)보다 빠릅니까?
- 14. 왜 내 Java 응용 프로그램이 AMD 프로세서에서 더 빠릅니까?
- 15. 왜 fsock_open()을 사용하는 것보다 file_get_contents()가 더 빠릅니까?
- 16. 왜이 정규 표현식이 더 빠릅니까?
- 17. 서버리스이기 때문에 SQLite가 더 빠릅니까?
- 18. mysql, ifnull과 coalesce는 더 빠릅니까?
- 19. 파이썬에서 목록이나 사전이 더 빠릅니까?
- 20. 어느 것이 더 빠릅니까? 연합인가?
- 21. 더 빠릅니까? NSXMLParser 또는 KissXML
- 22. PHP는 C++ 확장을 사용하면 더 빠릅니까?
- 23. 입력 된 기능 언어가 더 빠릅니까?
- 24. 루프 또는 while 루프가 더 빠릅니까?
- 25. 왜 xxx는 함수가 아닙니다.
- 26. 왜 gcc -o0은 icc -o0보다 빠릅니까?
- 27. 파이썬 함수가 왜 가비지 수집을합니까?
- 28. C의 시스템() 함수가 버그 출력을 표시합니다.
- 29. ActiveRecord to_xml의 드롭 인 대체품이 더 빠릅니까?
- 30. h2에 대한 다양한 옵션 - 더 빠릅니까?