Note that there are some explanatory texts on larger screens.

plurals
  1. POIs String.IndexOf(char) really slower than manual searching?
    primarykey
    data
    text
    <p>When doing a simple performance measurement, I was astonished to see that calling <code>String.IndexOf(char)</code> was actually slower than doing it manually! Is this really true?! Here is my test code:</p> <pre><code>const string str = @"91023m lkajsdfl;jkasdf;piou-09324\\adf \asdf\45\ 65u\ 86\ 8\\\;"; static int testIndexOf() { return str.IndexOf('\\'); } static int testManualIndexOf() { string s = str; for (int i = 0; i &lt; s.Length; ++i) if (s[i] == '\\') return i; return -1; } </code></pre> <p>I ran each method 25 million times, and measured the time using a <code>Stopwatch</code>. The manual version was consistently 25% faster than the other one.</p> <p>Any thoughts?!</p> <hr> <p><strong>Edit 2:</strong> Running the tests on a different machine with .NET 4.0 yields results very similar to those in Marc Gravell's answer. <strong><code>String.IndexOf(char)</code></strong> <em>is faster</em> than manual searching.</p> <hr> <p><strong>Edit:</strong> Today (Jan 4 '09) I wanted to check this issue in a more comprehensive way, so I created a new project, and wrote the code you'll find below. I got the following results when running release mode from cmd for 100 million iterations:</p> <pre><code> - String. IndexOf : 00:00:07.6490042 - MyString.PublicIndexOf : 00:00:05.6676471 - MyString.InternIndexOf : 00:00:06.1191796 - MyString.PublicIndexOf2: 00:00:09.1363687 - MyString.InternIndexOf2: 00:00:09.1182569 </code></pre> <p>I ran these tests at least 20 times, getting almost the same results every time. My machine is XP SP3, VS 2008 SP1, P4 3.0 GHz with no hyper-threading and 1 GB RAM. I find the results really strange. As you can see, <code>String.IndexOf</code> was about 33% slower than my <code>PublicIndexOf</code>. Even stranger, I wrote the same method as <code>internal</code>, and it was about 8% slower than the <code>public</code> one! I do not understand what's happening, and I hope you could help me understand!</p> <p>The testing code is below. (Sorry for the repeated code, but I found that using a delegate showed different timings, with the <code>public</code> and <code>internal</code> methods taking the same time.)</p> <pre><code>public static class MyString { public static int PublicIndexOf(string str, char value) { for (int i = 0; i &lt; str.Length; ++i) if (str[i] == value) return i; return -1; } internal static int InternIndexOf(string str, char value) { for (int i = 0; i &lt; str.Length; ++i) if (str[i] == value) return i; return -1; } public static int PublicIndexOf2(string str, char value, int startIndex) { if (startIndex &lt; 0 || startIndex &gt;= str.Length) throw new ArgumentOutOfRangeException("startIndex"); for (; startIndex &lt; str.Length; ++startIndex) if (str[startIndex] == value) return startIndex; return -1; } internal static int InternIndexOf2(string str, char value, int startIndex) { if (startIndex &lt; 0 || startIndex &gt;= str.Length) throw new ArgumentOutOfRangeException("startIndex"); for (; startIndex &lt; str.Length; ++startIndex) if (str[startIndex] == value) return startIndex; return -1; } } class Program { static void Main(string[] args) { int iterations = 100 * 1000 * 1000; // 100 millions char separator = '\\'; string str = @"91023m lkajsdfl;jkasdf;piou-09324\\adf \asdf\45\ 65u\ 86\ 8\\\;"; Stopwatch watch = new Stopwatch(); // test String.IndexOf int sum = 0; watch.Start(); for (int i = 0; i &lt; iterations; ++i) sum += str.IndexOf(separator); watch.Stop(); Console.WriteLine(" String. IndexOf : ({0}, {1})", watch.Elapsed, sum); // test MyString.PublicIndexOf sum = 0; watch.Reset(); watch.Start(); for (int i = 0; i &lt; iterations; ++i) sum += MyString.PublicIndexOf(str, separator); watch.Stop(); Console.WriteLine("MyString.PublicIndexOf : ({0}, {1})", watch.Elapsed, sum); // test MyString.InternIndexOf sum = 0; watch.Reset(); watch.Start(); for (int i = 0; i &lt; iterations; ++i) sum += MyString.InternIndexOf(str, separator); watch.Stop(); Console.WriteLine("MyString.InternIndexOf : ({0}, {1})", watch.Elapsed, sum); // test MyString.PublicIndexOf2 sum = 0; watch.Reset(); watch.Start(); for (int i = 0; i &lt; iterations; ++i) sum += MyString.PublicIndexOf2(str, separator,0); watch.Stop(); Console.WriteLine("MyString.PublicIndexOf2: ({0}, {1})", watch.Elapsed, sum); // test MyString.InternIndexOf2 sum = 0; watch.Reset(); watch.Start(); for (int i = 0; i &lt; iterations; ++i) sum += MyString.InternIndexOf2(str, separator,0); watch.Stop(); Console.WriteLine("MyString.InternIndexOf2: ({0}, {1})", watch.Elapsed, sum); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload