Редактировать:
Добавлен пример, который можно сделать с помощью оператора if-else, но не с условным оператором.
Перед ответом, пожалуйста, посмотрите [ Что быстрее? ] в блоге мистера Липперта. И я думаю, что ответ г-на Эрсонмеза является наиболее правильным здесь.
Я пытаюсь упомянуть кое-что, что мы должны иметь в виду с языком программирования высокого уровня.
Во-первых, я никогда не слышал, что условный оператор должен быть быстрее или с той же производительностью, что и оператор if-else в C♯ .
Причина проста: что если нет операции с оператором if-else:
if (i > 0)
{
value += 2;
}
else
{
}
Требование условного оператора состоит в том, что должно быть значение с любой стороны, а в C♯ также требуется, чтобы обе стороны имели:
одинаковый тип. Это просто отличает его от оператора if-else. Таким образом, ваш вопрос становится вопросом, спрашивающим, как генерируется инструкция машинного кода, так что разница в производительности.
С условным оператором семантически это:
Какое бы выражение ни оценивалось, оно имеет значение.
Но с оператором if-else:
Если выражение оценено как истинное, сделайте что-нибудь; если нет, сделай другое.
Значение не обязательно связано с оператором if-else. Ваше предположение возможно только с оптимизацией.
Другой пример, демонстрирующий разницу между ними:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
код выше компилирует, однако, заменить оператор if-else условным оператором просто не скомпилируется:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
Условный оператор и оператор if-else являются концептуальными, когда вы делаете одно и то же, возможно, это даже быстрее с условным оператором в C , так как C ближе к сборке платформы.
Для исходного кода, который вы предоставили, условный оператор используется в цикле foreach, который запутал бы вещи, чтобы увидеть разницу между ними. Поэтому я предлагаю следующий код:
public static class TestClass {
public static void TestConditionalOperator(int i) {
long value=0;
value+=i>0?2:3;
}
public static void TestIfElse(int i) {
long value=0;
if(i>0) {
value+=2;
}
else {
value+=3;
}
}
public static void TestMethod() {
TestConditionalOperator(0);
TestIfElse(0);
}
}
и следующие две версии ИЛ оптимизированы и нет. Поскольку они длинные, я использую изображение, чтобы показать, правая часть оптимизирована:
(Нажмите, чтобы увидеть полноразмерное изображение.)
В обеих версиях кода IL условного оператора выглядит короче, чем оператор if-else, и все еще остается сомнение в окончательном генерировании машинного кода. Ниже приведены инструкции для обоих методов, и первое изображение не оптимизировано, а второе оптимизировано:
Неоптимизированные инструкции: (Нажмите, чтобы увидеть полноразмерное изображение.)
Оптимизированные инструкции: (Нажмите, чтобы увидеть полноразмерное изображение.)
В последнем случае желтый блок - это код, который выполняется только тогда i<=0
, а синий - когда i>0
. В любой версии инструкций оператор if-else короче.
Обратите внимание, что для разных инструкций [ ИПЦ ] не обязательно одинаков. Логично, что для идентичной инструкции больше инструкций обходится дольше в цикл. Но если время выборки команд и канал / кэш также были приняты во внимание, то реальное общее время выполнения зависит от процессора. Процессор также может прогнозировать ответвления.
Современные процессоры имеют еще больше ядер, с этим все может быть сложнее. Если вы были пользователем процессора Intel, вам, возможно, захочется взглянуть на [ Справочное руководство по оптимизации архитектур Intel® 64 и IA-32 ].
Я не знаю, был ли аппаратно-реализованный CLR, но если да, вы, вероятно, быстрее справитесь с условным оператором, потому что IL явно меньше.
Примечание: весь машинный код x86.
DateTime
для измерения производительности. ИспользованиеStopwatch
. Далее, время довольно длинное - это очень короткое время для измерения.