Digital Olympics. Delegates vesus if-else-if

Using int comparisons, there is barely any difference between if-else-if or invoking a pre-determined delegate?

Options   Delegate   if-else-if   switch
2         1203       1078(-125)   1094(-109)
3         1078       1156(78)     1125(47)
4         1031       1204(173)    1187(156)
5         1141       1218(77)     1188(47)
6         1094       1203(109)    1187(93)

Conclusion: there is barely any difference

  • If there are only 2 options, if seems to run slightly faster than delegate invocation(5%)
  • delegate invocation runs faster, if there are randomly 3 choices or more. With 6 options, 15%

The thought process behind the below program, is once you’ve determined the data you are getting, is it better execution time, to have a delegate assigned specifically for that data and execute that delegate. Or to have nested if-else-if statements checking each time, what the appropriate series of commands it is to execute for that datatype.

It’s not as obvious as it may seem. 6 if‘s executed before executing delegate in loop vs 6000000 if‘s in a loop. Executing a delegate has a cost to it, over a non-virtualized method, because it has to evaluate the pointer contents. But there is an advantage, but only if you had of millions of iterations. The advantage gained is like counting exact change at the cashier, to save time getting change back. So use if‘s to your heart’s content until you find a compelling reason to use delegates.

int trials = 7;
int[] a = new int[trials];
int[] b = new int[trials];
int SIZE = 1000000;

Random rnd = new Random();
for (int j = 2; j < trials; j++)
{
    Console.WriteLine("Trying {0} options", j);
    var option = rnd.Next(j);

    Console.Write("Testing delegate invocation... ");
    var start1 = Environment.TickCount;
    Convertor converter = null;
    if (option == 0)
        converter = ToInt32;
    else if (option == 1)
        converter = ToInt64;
    else if (option == 2)
        converter = ToDbl;
    else if (option == 3)
        converter = ToDecimal;
    else if (option == 4)
        converter = ToSgl;
    else if (option == 5)
        converter = ToByte;
    else if (option == 6)
        converter = ToChar;

    for (int i = 0; i < SIZE; i++)
    {
        option = rnd.Next(j); //just here to occupy cpu, to maintain relative performance
        var value = rnd.Next(255).ToString();
        var boxed = converter(value);
    }
    var end1 = Environment.TickCount - start1;
    a[j] = end1;
    Console.WriteLine(end1);


    Console.Write("Testing if else if invocation... ");
    var start2 = Environment.TickCount;
    for (int i = 0; i < SIZE; i++)
    {
        option = rnd.Next(j); //even out which if statement gets called, ie it 0-2, then it should average to 1
        var value = rnd.Next(255).ToString();
        object boxed;
        if (option == 0)
            boxed = ToInt32(value);
        else if (option == 1)
            boxed = ToInt64(value);
        else if (option == 2)
            boxed = ToDbl(value);
        else if (option == 3)
            boxed = ToDecimal(value);
        else if (option == 4)
            boxed = ToSgl(value);
        else if (option == 5)
            boxed = ToByte(value);
        else if (option == 6)
            boxed = ToChar(value);
    }
    var end2 = Environment.TickCount - start2;
    b[j] = end2;
    Console.WriteLine(end2);
}

Leave a Reply

Your email address will not be published. Required fields are marked *