Редагувати:
Додано приклад, який можна зробити за допомогою оператора 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 оператор коротший.
Зауважте, що для різних інструкцій [ CPI ] необов’язково однаковий. Логічно, для однакової інструкції більше інструкцій коштує довший цикл. Але якщо час отримання інструкцій та кеш / кеш також враховувались, то реальний загальний час виконання залежить від процесора. Процесор також може передбачити гілки.
Сучасні процесори мають ще більше ядер, з цим все може бути складніше. Якщо ви були користувачем процесорів Intel, можливо, ви захочете ознайомитись з посібником з оптимізації архітектури Intel® 64 та IA-32 ].
Я не знаю, чи існував апаратно реалізований CLR, але якщо так, то, ймовірно, ви швидше ставитеся до умовного оператора, оскільки ІЛ явно менше.
Примітка: Усі машинні коди мають x86.
DateTime
для вимірювання продуктивності. ВикористовуйтеStopwatch
. Далі, час довше - це дуже короткий час для вимірювання.