Сравните производительность команд if-else и switch в C#

Пример Сравните скорости условного оператора (тройной оператор? 🙂 и оператор if-else в C# сравнивает производительность двух видов условных тестов. Джонни Бой отметил, что это не включает другой условный оператор: switch. он также ссылался на другую статью, которая делает это сравнение: C# .Net : Какова самая быстрая условная формулировка? . Вывод этой статьи заключался в том, что if-else превосходит остальные на небольшую сумму.

Но это не совсем вся история. Конструкции if-else и ?: имеют очень схожую производительность, поскольку они переводятся в одну и ту же структуру в IL-коде. Однако оператор switch делает что-то другое. Вместо того, чтобы просто сравнивать его значение с последовательностью других значений по одному, он создает таблицу поиска, которая позволяет быстро перейти к соответствующей части таблицы для значения.

Кстати, Visual Basic не обрабатывает операторы Select Case (операторы switch в Visual Basic) таким же образом. Он преобразует выражения Select Case в последовательность операторов If Then Else. Это позволяет Visual Basic добавлять дополнительные функции в Select Case. Например, оператор Case может включать в себя несколько значений и диапазонов, как в Case 0, 20, 40, 100 To 1000.

В любом случае, поскольку switch фактически не сравнивает свое значение с значениями case, он может достичь более высокой производительности, чем if-else, когда условия правильные.

В этом примере используется метод RunTrials для сравнения последовательности операторов if-else с оператором switch.

// Запуск проб с заданным количеством значений.
Stopwatch Watch = new Stopwatch();
Random Rand = new Random();
private void RunTrials(int num_values, int num_trials,
    TextBox txtIf, TextBox txtSwitch, TextBox txtDiff)
{
    Stopwatch watch = new Stopwatch();

    // if-then-else.
    Watch.Reset();
    Watch.Start();
    for (int trial = 0; trial < num_trials; trial++)
    {
        int result = -1;
        int value = Rand.Next(0, num_values);
        if (value == 0) result = 0;
        else if (value == 1) result = 1;
        else if (value == 2) result = 2;
        else if (value == 3) result = 3;
        ... More lines omitted ...
        else if (value == 49) result = 49;
        value = result;
    }
    Watch.Stop();
    double if_seconds = Watch.Elapsed.TotalSeconds;
    txtIf.Text = if_seconds.ToString("0.0000");
    txtIf.Refresh();

    // if-then-else.
    Watch.Reset();
    Watch.Start();
    for (int trial = 0; trial < num_trials; trial++)
    {
        int result = -1;
        int value = Rand.Next(0, num_values);
        switch (value)
        {
            case 0: result = 0; break;
            case 1: result = 1; break;
            case 2: result = 2; break;
            case 3: result = 3; break;
            ... More lines omitted ...
            case 49: result = 49; break;
        }
        value = result;
    }
    Watch.Stop();
    double switch_seconds = Watch.Elapsed.TotalSeconds;
    txtSwitch.Text = switch_seconds.ToString("0.0000");
    txtSwitch.Refresh();

    double diff = 100.0 * (if_seconds - switch_seconds) /
        if_seconds;
    txtDiff.Text = diff.ToString("0.0000");
    txtDiff.Refresh();
}

Параметр num_values указывает количество значений, которые могут возникнуть в пробной версии. Например, если num_values равно 10, тогда тест использует числа от 0 до 9. Это означает, что операторы if-else будут завершены после не более 10 операторов. Оператор switch всегда включает в себя 50 case операторов, хотя в этом случае он будет использовать только первые 10.

Для каждого испытания метод генерирует случайное число в пределах требуемого диапазона. Затем он использует это значение для проверки последовательности инструкций if-else.

После того, как он завершил испытания if-else, программа повторяет испытания для оператора switch.

Если вы внимательно посмотрите на изображение выше, вы увидите, что оператор switch работает быстрее, чем операторы if-else в каждом случае с увеличением процентной разницы по мере увеличения диапазона значений. Это имеет смысл, потому что среднее время, необходимое для нахождения значения операторами if-else, увеличивается с увеличением диапазона значений. Напротив, оператор switch использует таблицу поиска, поэтому поиск определенного элемента в таблице занимает примерно одинаковое количество времени в каждом случае.

Мораль: switch быстрее if-else, если у вас есть много случаев, чтобы проверить, и чем больше случаев у вас есть больше времени switch сохраняет.

Источник: http://csharphelper.com/blog/2015/08/compare-the-performance-of-if-else-and-switch-statements-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector