[c#] 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 (s2)는 IndexOf (s2)보다 여러 배 (내 컴퓨터에서 10 배) 더 빠릅니다. Contains는 IndexOf가 기본적으로 수행하는 문화권 감지 검색보다 빠른 StringComparison.Ordinal을 사용하기 때문입니다 (하지만 .net 4.0에서 변경 될 수 있음 http : //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에게 감사드립니다).

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

  • IndexOf 533ms.
  • 266ms를 포함합니다.

:-/

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


답변

Reflector를 사용하면 포함이 IndexOf를 사용하여 구현되었음을 알 수 있습니다. 다음은 구현입니다.

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

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


답변

코드를 마이크로 최적화하려면 항상 벤치마킹하는 것이 가장 좋습니다.

.net 프레임 워크에는 뛰어난 스톱워치 구현이 있습니다 -System.Diagnostics.Stopwatch


답변

조금 읽어 보면 String.Contains 메서드가 단순히 String.IndexOf를 호출하는 것으로 보입니다. 차이점은 String.Contains는 부울을 반환하는 반면 String.IndexOf는 (-1)이 하위 문자열을 찾을 수 없음을 나타내는 정수를 반환한다는 것입니다.

100,000 회 정도의 반복으로 작은 테스트를 작성하고 직접 확인하는 것이 좋습니다. 내가 추측한다면 IndexOf가 약간 더 빠를 수 있지만 내가 말한 것처럼 그냥 추측이라고 말하고 싶습니다.

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