Сравните производительность команд if-else и switch в C#
Пример Сравните скорости условного оператора (тройной оператор? 🙂 и оператор if-else в C# сравнивает производительность двух видов условных тестов. Джонни Бой отметил, что это не включает другой условный оператор: switch. он также ссылался на другую статью, которая делает это сравнение:
Но это не совсем вся история. Конструкции if-else и ?: Tt> имеют очень схожую производительность, поскольку они переводятся в одну и ту же структуру в 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, когда условия правильные. p >
В этом примере используется метод 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 сохраняет.