I read everywhere that ternary operator is supposed to be faster than, or at least the same as, its equivalent if
-else
block.
However, I di
EDIT: All change... see below.
I can't reproduce your results on the x64 CLR, but I can on x86. On x64 I can see a small difference (less than 10%) between the conditional operator and the if/else, but it's much smaller than you're seeing.
I've made the following potential changes:
/o+ /debug-
, and run outside the debuggerStopwatch
Results with /platform:x64
(without the "ignore" lines):
if/else with 1 iterations: 17ms
conditional with 1 iterations: 19ms
if/else with 1000 iterations: 17875ms
conditional with 1000 iterations: 19089ms
Results with /platform:x86
(without the "ignore" lines):
if/else with 1 iterations: 18ms
conditional with 1 iterations: 49ms
if/else with 1000 iterations: 17901ms
conditional with 1000 iterations: 47710ms
My system details:
So unlike before, I think you are seeing a real difference - and it's all to do with the x86 JIT. I wouldn't like to say exactly what is causing the difference - I may update the post later on with more details if I can bother to go into cordbg :)
Interestingly, without sorting the array first, I end up with tests which take about 4.5x as long, at least on x64. My guess is that this is to do with branch prediction.
Code:
using System;
using System.Diagnostics;
class Test
{
static void Main()
{
Random r = new Random(0);
int[] array = new int[20000000];
for(int i = 0; i < array.Length; i++)
{
array[i] = r.Next(int.MinValue, int.MaxValue);
}
Array.Sort(array);
// JIT everything...
RunIfElse(array, 1);
RunConditional(array, 1);
// Now really time it
RunIfElse(array, 1000);
RunConditional(array, 1000);
}
static void RunIfElse(int[] array, int iterations)
{
long value = 0;
Stopwatch sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
foreach (int i in array)
{
if (i > 0)
{
value += 2;
}
else
{
value += 3;
}
}
}
sw.Stop();
Console.WriteLine("if/else with {0} iterations: {1}ms",
iterations,
sw.ElapsedMilliseconds);
// Just to avoid optimizing everything away
Console.WriteLine("Value (ignore): {0}", value);
}
static void RunConditional(int[] array, int iterations)
{
long value = 0;
Stopwatch sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
foreach (int i in array)
{
value += i > 0 ? 2 : 3;
}
}
sw.Stop();
Console.WriteLine("conditional with {0} iterations: {1}ms",
iterations,
sw.ElapsedMilliseconds);
// Just to avoid optimizing everything away
Console.WriteLine("Value (ignore): {0}", value);
}
}