Нужно знать производительность коммутатора C # - PullRequest
4 голосов
/ 16 декабря 2011

Предположим, что есть какой-то метод, например

static string switchExample(string abc){
    switch(abc.ToUpper()) {
        case "123":
            return "Numeric";
        case "ab":
            return "Alphabets";
        default:
            return "symbol";
    }
}

. Теперь мне нужно узнать, есть ли проблемы с производительностью для использования нескольких точек выхода (возврат в каждом случае), как я делал вкод для передачи обновленного значения за один раз путем создания некоторой временной строки в начале и заполнения ее соответствующим регистром соответствия.

Ответы [ 2 ]

4 голосов
/ 16 декабря 2011

Тестирование с помощью Visual Studio 11 Developer Preview показывает, что если в вашем операторе switch меньше 7 случаев (6 случаев и значение по умолчанию), то компилятор генерирует серию операторов if.Ваш пример кода преобразуется в эквивалент:

string s = abc.ToLower();
if (s == "123") return "Numeric";
if (s == "ab") return "Alphabetic";
return "symbol";

Если есть 7 или более случаев, компилятор генерирует код, который создает словарь, сопоставляя строки с последовательными целыми числами.Затем он использует оператор IL switch (который аналогичен вычисленному goto на других языках) для перехода к другому коду на основе значений.

Код генерируется таким образом, что словарь создается только один раз.- первый раз выполняется оператор switch.Последующее использование этого оператора switch не требует повторного создания словаря.

С точки зрения эффективности код компилятора, сгенерированный для небольшого оператора switch, эквивалентен множественным операторам if.Когда имеется более 6 случаев (включая значение по умолчанию), поиск в словаре компилятора будет выполняться быстрее, чем несколько операторов switch.

Обратите внимание, что мои числа основаны на очень маленькой выборке (несколько тестов) с использованиемпредварительный просмотр невыпущенной версии компилятора.Предыдущие версии компилятора могли иметь другое пороговое значение или могли использовать другие методы, и окончательная версия нового компилятора могла бы действовать иначе, чем я описал выше.Я бы не стал рассчитывать ни на одну из этих деталей реализации.

Короче, напишите switch.Пусть компилятор беспокоится о том, как сделать это быстрее.

4 голосов
/ 16 декабря 2011

Теперь здесь мне не нужно, есть ли проблемы с производительностью для использования нескольких точек выхода

Ваш вопрос является воплощением преждевременной оптимизации.

Мое предложение,если вы действительно хотите знать, это написать метод в обоих направлениях - один раз с операторами return в каждом случае и один раз с одним возвратом после оператора switch.Затем декомпилируйте каждый из них на промежуточный язык для сравнения.

Вы по-прежнему не сможете сделать какое-то определенное утверждение о производительности, не выполнив фактическое измерение с помощью профилирования.

Но я думаю, что это довольно безопасноскажем, что любая разница, если таковая будет, будет крайне незначительной.Конечный результат должен быть не чем иным, как сравнением значения с константными строками, а при совпадении - сдвигом значения, стека и возвратом.Компилятор, скорее всего, оптимизирует удаление временной переменной, видя, что она будет использоваться только как возвращаемое значение.

Кроме того, некоторые операторы switch значительно оптимизированы компилятором.См. https://stackoverflow.com/a/395965/224087 и https://stackoverflow.com/a/126507/224087 для получения дополнительной информации о производительности и оптимизации операторов коммутации.

Этот код, для которого вы ставите под сомнение производительность, будет состоять лишь из нескольких операций ЦП -по-настоящему крошечное количество времени для беспокойства.

...