title: What is the fastest, case insensitive, way to see if a string contains another string in C#?
body: <p>EDIT 2:</p>
  
  <p>Confirmed that my performance problems were due to the static function call to the StringExtensions class.  Once removed, the IndexOf method is indeed the fastest way of accomplishing this.</p>
  
  <p>What is the fastest, case insensitive, way to see if a string contains another string in C#?  I see the accepted solution for the post here at <a href="https://stackoverflow.com/questions/444798/case-insensitive-containsstring">Case insensitive &#39;Contains(string)&#39;</a> but I have done some preliminary benchmarking and it seems that using that method results in orders of magnitude slower calls on larger strings (> 100 characters) whenever the test string cannot be found.</p>
  
  <p>Here are the methods I know of:</p>
  
  <p>IndexOf:</p>
  
  <pre><code>public static bool Contains(this string source, string toCheck, StringComparison comp)
  {
      if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
          return false;
  
      return source.IndexOf(toCheck, comp) &gt;= 0;
  } 
  </code></pre>
  
  <p>ToUpper:</p>
  
  <pre><code>source.ToUpper().Contains(toCheck.ToUpper());
  </code></pre>
  
  <p>Regex:</p>
  
  <pre><code>bool contains = Regex.Match("StRiNG to search", "string", RegexOptions.IgnoreCase).Success;
  </code></pre>
  
  <p>So my question is, which really is the fastest way on average and why so?</p>
  
  <p>EDIT:</p>
  
  <p>Here is my simple test app I used to highlight the performance difference.  Using this, I see 16 ms for ToLower(), 18 ms for ToUpper and 140 ms for the StringExtensions.Contains():</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Globalization;
  
  namespace ScratchConsole
  {
      class Program
      {
      static void Main(string[] args)
      {
          string input = "";
          while (input != "exit")
          {
              RunTest();
              input = Console.ReadLine();
          }
      }
  
      static void RunTest()
      {
          List&lt;string&gt; s = new List&lt;string&gt;();
          string containsString = "1";
          bool found;
          DateTime now;
          for (int i = 0; i &lt; 50000; i++)
          {
              s.Add("AAAAAAAAAAAAAAAA AAAAAAAAAAAA");
          }
  
          now = DateTime.Now;
          foreach (string st in s)
          {
              found = st.ToLower().Contains(containsString);
          }
          Console.WriteLine("ToLower(): " + (DateTime.Now - now).TotalMilliseconds);
  
          now = DateTime.Now;
          foreach (string st in s)
          {
              found = st.ToUpper().Contains(containsString);
          }
          Console.WriteLine("ToUpper(): " + (DateTime.Now - now).TotalMilliseconds);
  
  
          now = DateTime.Now;
          foreach (string st in s)
          {
              found = StringExtensions.Contains(st, containsString, StringComparison.OrdinalIgnoreCase);
          }
          Console.WriteLine("StringExtensions.Contains(): " + (DateTime.Now - now).TotalMilliseconds);
  
      }
  }
  
  public static class StringExtensions
  {
      public static bool Contains(this string source, string toCheck, StringComparison comp)
      {
          return source.IndexOf(toCheck, comp) &gt;= 0;
      }
  }
  </code></pre>
  
  <p>}</p>