In fact, it may be somewhat faster, despite some comments here.
Let me actually check it out:
using System; using System.Diagnostics; namespace Demo { class Program { static void Main(string[] args) { int count = 1000000000; Stopwatch sw = Stopwatch.StartNew(); for (int way = 1; way <= 3; ++way) test1(count, way); var elapsed1 = sw.Elapsed; Console.WriteLine("test1() took " + elapsed1); sw.Restart(); for (int way = 1; way <= 3; ++way) test2(count, way); var elapsed2 = sw.Elapsed; Console.WriteLine("test2() took " + elapsed2); Console.WriteLine("test2() was {0:f1} times as fast.", + ((double)elapsed1.Ticks)/elapsed2.Ticks); } static void test1(int count, int way) { for (int i = 0; i < count; ++i) { switch (way) { case 1: doWork1(); break; case 2: doWork2(); break; case 3: doWork3(); break; } } } static void test2(int count, int way) { switch (way) { case 1: for (int i = 0; i < count; ++i) doWork1(); break; case 2: for (int i = 0; i < count; ++i) doWork2(); break; case 3: for (int i = 0; i < count; ++i) doWork3(); break; } } static void doWork1() { } static void doWork2() { } static void doWork3() { } } }
Now this is completely unrealistic, since the doWork () methods do nothing. However, this will give us base time.
The results that I get to build RELEASE on my Windows 7 x64 system are as follows:
test1() took 00:00:03.8041522 test2() took 00:00:01.7916698 test2() was 2.1 times as fast.
Therefore, moving the loop to the switch statement makes it MORE THAN TWICE AS FAST.
Now let's make it a little more realistic by adding some code to doWork ():
using System; using System.Diagnostics; namespace Demo { class Program { static void Main(string[] args) { int count = 1000000000; Stopwatch sw = Stopwatch.StartNew(); for (int way = 1; way <= 3; ++way) test1(count, way); var elapsed1 = sw.Elapsed; Console.WriteLine("test1() took " + elapsed1); sw.Restart(); for (int way = 1; way <= 3; ++way) test2(count, way); var elapsed2 = sw.Elapsed; Console.WriteLine("test2() took " + elapsed2); Console.WriteLine("test2() was {0:f1} times as fast.", + ((double)elapsed1.Ticks)/elapsed2.Ticks); } static int test1(int count, int way) { int total1 = 0, total2 = 0, total3 = 0; for (int i = 0; i < count; ++i) { switch (way) { case 1: doWork1(i, ref total1); break; case 2: doWork2(i, ref total2); break; case 3: doWork3(i, ref total3); break; } } return total1 + total2 + total3; } static int test2(int count, int way) { int total1 = 0, total2 = 0, total3 = 0; switch (way) { case 1: for (int i = 0; i < count; ++i) doWork1(i, ref total1); break; case 2: for (int i = 0; i < count; ++i) doWork2(i, ref total2); break; case 3: for (int i = 0; i < count; ++i) doWork3(i, ref total3); break; } return total1 + total2 + total3; } static void doWork1(int n, ref int total) { total += n; } static void doWork2(int n, ref int total) { total += n; } static void doWork3(int n, ref int total) { total += n; } } }
Now I get the following results:
test1() took 00:00:03.9153776 test2() took 00:00:05.3220507 test2() was 0.7 times as fast.
Now SLOWER puts the loop in the switch! This counterintuitive result is typical of these things and demonstrates why you should ALWAYS run time tests when you try to optimize your code. (And, as a rule, you should not do optimizing such code if you have no good reason to suspect that there is a bottleneck. You better spend time cleaning up your code.))
I did some other tests, and for the slightly simpler doWork () methods, the test2 () method was faster. This very much depends on what the JIT compiler can do with optimization.
NOTE. I think the reason for the speed differences for my second test code is because the JIT compiler can optimize the 'ref' calls when inlaying doWork () calls when they are not in a loop, like in test1 (); whereas for test2 () it cannot (for some reason).