Is String.Contains() faster than String.IndexOf()?

123,105

Solution 1

Contains calls IndexOf:

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

Which calls CompareInfo.IndexOf, which ultimately uses a CLR implementation.

If you want to see how strings are compared in the CLR this will show you (look for CaseInsensitiveCompHelper).

IndexOf(string) has no options and Contains()uses an Ordinal compare (a byte-by-byte comparison rather than trying to perform a smart compare, for example, e with é).

So IndexOf will be marginally faster (in theory) as IndexOf goes straight to a string search using FindNLSString from kernel32.dll (the power of reflector!).

Updated for .NET 4.0 - IndexOf no longer uses Ordinal Comparison and so Contains can be faster. See comment below.

Solution 2

Contains(s2) is many times (in my computer 10 times) faster than IndexOf(s2) because Contains uses StringComparison.Ordinal that is faster than the culture sensitive search that IndexOf does by default (but that may change in .net 4.0 http://davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx).

Contains has exactly the same performance as IndexOf(s2,StringComparison.Ordinal) >= 0 in my tests but it's shorter and makes your intent clear.

Solution 3

I am running a real case (in opposite to a synthetic benchmark)

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

versus

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

It is a vital part of my system and it is executed 131,953 times (thanks DotTrace).

However shocking surprise, the result is the opposite that expected

  • IndexOf 533ms.
  • Contains 266ms.

:-/

net framework 4.0 (updated as for 13-02-2012)

Solution 4

If you really want to micro optimise your code your best approach is always benchmarking.

The .net framework has an excellent stopwatch implementation - System.Diagnostics.Stopwatch

Solution 5

By using Reflector, you can see, that Contains is implemented using IndexOf. Here's the implementation.

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

So Contains is likely a wee bit slower than calling IndexOf directly, but I doubt that it will have any significance for the actual performance.

Share:
123,105

Related videos on Youtube

Kb.
Author by

Kb.

Currently trying to migrate complex scheduling data using C#, Teams and SQL with Dapper

Updated on July 08, 2022

Comments

  • Kb.
    Kb. almost 2 years

    I have a string buffer of about 2000 characters and need to check the buffer if it contains a specific string.
    Will do the check in a ASP.NET 2.0 webapp for every webrequest.

    Does anyone know if the String.Contains method performs better than String.IndexOf method?

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

    Fun fact

    • Samuel Hicks
      Samuel Hicks over 15 years
      If you need to do this a billion times per web request, I would begin to take a look at stuff like this. In any other case, I would not bother, since the time spent in either method will most likely be incredibly insignificant compared to receiving the HTTP request in the first place.
    • Slai
      Slai over 7 years
      One of the keys to optimization is to test instead of assuming, because it can depend on a lot of factors such as .NET version, operating system, hardware, variation in the input, etc. In a lot of cases test results done by others can be very different on your system.
  • Gonzalo Quero
    Gonzalo Quero over 15 years
    Yes, but to use indexof as a bool, he would have to do the comparison outside the function. That would most likely give the same result as Contains, wouldn't it?
  • Brian Rasmussen
    Brian Rasmussen over 15 years
    Probably, but you do save one method call (unless it can be inlined). As I said, it will probably never be significant.
  • gary
    gary about 14 years
    Hi phild on a separate thread updated this with a version from tomasp.net/articles/ahocorasick.aspx which, providing your keywords (needles) don't change is a lot quicker.
  • Stephen Kennedy
    Stephen Kennedy about 12 years
    The changes in .NET 4.0 were apparently reverted before it went RTM so I wouldn't rely on that article too much blogs.msdn.com/bclteam/archive/2008/11/04/…
  • Eric Yin
    Eric Yin about 12 years
    because INT is much larger than BOOL, and IndexOf>=0 cause one more step
  • Davi Fiamenghi
    Davi Fiamenghi over 11 years
    You forgot to use ´StringComparison.Ordinal´
  • Mike Stockdale
    Mike Stockdale about 10 years
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.
  • David Schmitt
    David Schmitt almost 10 years
    the linked library is only one of many, and not the main thrust of the answer. I do not think that posting the libraries source or description would improve the answer, this site or the world.
  • Admin
    Admin almost 10 years
    -1 ; the question was "Does anyone know if the String.Contains method performs better than String.IndexOf method?" - your answer is "use a benchmark library", which basically means "I don't know, do it yourself", "this depends", which means "I don't know", and "get a running version and profile", which also means "I don't know, do it yourself". This isn't 'Jeopardy' - please provide an answer to the question asked, not how-to ideas - their place is in comments.
  • pzaj
    pzaj over 8 years
    This answer is nowhere near correct, just take a look here stackoverflow.com/posts/498880/revisions for the explanation
  • MordechayS
    MordechayS over 8 years
    My answer is 7 years old and based on the .NET 2 framework. Version 4 IndexOf() does indeed use StringComparison.CurrentCulture and Contains() uses StringComparison.Ordinal which will be faster. But really the speed differences we're talking about are minute - the point is one calls the other, and Contains is more readable if you don't need the index. In other words don't worry about it.
  • Raphaël
    Raphaël about 7 years
    throw new OutOfScopeException();
  • Jeremy Thompson
    Jeremy Thompson over 4 years
    It's the best but if you want a quick approach just press the pause button in a debug session. The code control is likely to halt in the slowest part roughly 50% of the time.
  • Default
    Default almost 4 years
    @JeremyThompson repeat the "pause debug" method like 10 times and you got yourself a profiler
  • CSharper
    CSharper over 3 years
    Tried it today on a 1.3 GB text file. Amongst others every line is checked for existence of a '@' char. 17.000.000 calls to Contains/IndexOf are made. Result: 12.5 sec for all Contains() calls, 2.5 sec for all IndexOf() calls. => IndexOf performs 5 times faster!! (.Net 4.8)
  • Diomedes Domínguez
    Diomedes Domínguez about 3 years
    @CSharper can you please share the source code of this benchmark?