IT story

String.Contains ()가 String.IndexOf ()보다 빠릅니까?

hot-time 2020. 8. 3. 17:36
반응형

String.Contains ()가 String.IndexOf ()보다 빠릅니까?


약 2000 자의 문자열 버퍼가 있으며 특정 문자열이 포함되어 있으면 버퍼를 확인해야합니다.
모든 웹 요청에 대해 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);

재미있는 사실


Contains전화 IndexOf:

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

어떤 호출 CompareInfo.IndexOf은 궁극적으로 CLR 구현을 사용합니다.

당신이 문자열이 CLR에서 비교하는 방법을 보려면 이 방법을 보여줍니다 (대한 모습 CaseInsensitiveCompHelper ).

IndexOf(string)옵션이 없으며 Contains()서수 비교 (예 : e를 사용하여 스마트 비교를 수행하는 대신 바이트 단위 비교)를 사용합니다.

따라서 kernel32.dll의 FindNLSString (반사기의 힘)을 사용하여 문자열을 검색하면 IndexOf이론적으로 IndexOf훨씬 빠릅니다 .

.NET 4.0 업데이트 - 같이 IndexOf는 더 이상 서수 비교를 사용하지 않습니다 그래서 빠를 수 있습니다 포함되어 있습니다. 아래의 의견을 참조하십시오.


아마 전혀 중요하지 않을 것입니다. Coding Horror;)에서이 게시물을 읽으십시오 : http://www.codinghorror.com/blog/archives/001218.html


Contains는 StringComparison.Ordinal을 사용하기 때문에 IndexOf (s2)보다 IndexOf (s2)보다 여러 번 (내 컴퓨터에서는 10 배) 빠릅니다 . //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx ).

포함은 내 테스트에서 IndexOf (s2, StringComparison.Ordinal)> = 0과 동일한 성능을 갖지만 더 짧아서 의도를 명확하게 만듭니다.


실제 사례를 실행하고 있습니다 (합성 벤치 마크와 반대)

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

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

그것은 내 시스템의 중요한 부분이며 131,953 번 실행됩니다 (DotTrace 덕분에).

그러나 충격적인 놀라움 , 결과는 예상과 반대입니다.

  • 533ms의 색인.
  • 266ms를 포함합니다.

:-/

net framework 4.0 (2012 년 2 월 2 일 업데이트)


Reflector를 사용하면 Contains가 IndexOf를 사용하여 구현되었음을 알 수 있습니다. 구현은 다음과 같습니다.

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

따라서 Contains는 IndexOf를 직접 호출하는 것보다 약간 느릴 수 있지만 실제 성능에 어떤 의미가 있는지 의심합니다.


실제로 코드를 마이크로 최적화하려는 경우 가장 좋은 방법은 항상 벤치마킹입니다.

.net 프레임 워크는 System.Diagnostics.Stopwatch 라는 훌륭한 스톱워치 구현을 갖습니다.


약간의 독서에서, 후드 아래에서 String.Contains 메소드는 단순히 String.IndexOf를 호출하는 것으로 보입니다. 차이점은 String.Contains는 부울을 반환하고 String.IndexOf는 하위 문자열을 찾을 수 없음을 나타내는 (-1)로 정수를 반환합니다.

나는 100,000 번 정도의 반복으로 작은 테스트를 작성하는 것이 좋습니다. 추측한다면 IndexOf가 약간 빠를 수도 있지만 추측 한 것처럼 말입니다.

Jeff Atwood는 그의 블로그 에서 문자열에 관한 좋은 기사를 가지고 있습니다 . 연결에 관한 것이지만 그럼에도 도움이 될 수 있습니다.


이것에 대한 업데이트처럼 일부 테스트를 수행하고 입력 문자열을 제공하는 것이 상당히 큽니다. 병렬 정규식은 내가 찾은 가장 빠른 C # 방법입니다 (상상 한 코어가 두 개 이상 있음)

예를 들어 총 일치 량 얻기-

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

도움이 되었기를 바랍니다!


Jon Skeet이 최근에 발표 한 벤치 마크 라이브러리를 사용 하여 측정하십시오.

주의 사항

모든 (마이크로) 성능 질문으로, 이것은 사용중인 소프트웨어 버전, 검사 된 데이터의 세부 사항 및 통화를 둘러싼 코드에 따라 다릅니다.

모든 (마이크로) 성능 질문으로, 첫 번째 단계는 유지 보수가 용이 한 실행 버전을 얻는 것입니다. 그런 다음 벤치마킹, 프로파일 링 및 튜닝을 추측하는 대신 측정 된 병목 현상에 적용 할 수 있습니다.


For anyone still reading this, indexOf() will probably perform better on most enterprise systems, as contains() is not compatible with IE!

참고URL : https://stackoverflow.com/questions/498686/is-string-contains-faster-than-string-indexof

반응형