2015-05-15 2 views
0

Я выполнил должное внимание, чтобы узнать, было ли это задано раньше и не найдено ничего похожего, но близко.Тернар против Цепного Если-else-if (Спектакль)

Скажите, что у меня есть цепочка операторов if-else-if.

foreach (value in valueList) 
    if (value == 120) { 
     w = true; 
    } else if (value == 140) { 
     x = true; 
    } else if (value == 160) { 
     y = true; 
    } else if (value == 180) { 
     z = true; 
    } 
} 

Есть ли какие-либо преимущества изменяя еще, если цепь трехкомпонентных выражений, таких как:

foreach (value in valueList) { 
    w = (value == 120) ? true : false; 
    x = (value == 140) ? true : false; 
    y = (value == 160) ? true : false; 
    z = (value == 180) ? true : false; 
} 

Мой первый наклон нет. Из-за цикла forкаждое задание выполняется каждый раз, когда происходит цикл. Если в цепочке if-else-if назначение выполняется только один раз. Но сравнения делаются чаще (правда?). Может ли кто-нибудь решить это для меня?

Я знаю, что switch легко победит обоих с точки зрения производительности. Могу ли я обосновать этот вопрос в предположении, что использование switch не является вариантом?

Я думаю, что еще один вопрос в этом вопросе будет состоять в том, какие сравнения между двумя?

+3

Как насчет использования 'switch'? –

+0

Переключатель легко бьет оба, я думал, что упомянул об этом ... нет. – gh0st

+2

Это не эквивалент. Если 'valuelist' содержит все четыре числа, по порядку, после первого цикла все четыре переменные будут истинными. После второго цикла будет истинно только 'z'. –

ответ

2

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

Это говорит о том, что использование тройного оператора во втором коде очень плохо. Вы можете просто присвоить результат сравнения непосредственно:

w = value == 120; 
x = value == 140; 
y = value == 160; 
z = value == 180; 

Taking в сторону семантики, это будет также сделать это, вероятно, немного более производительным, чем если/другое конструкции. Вы можете подумать, что просто запустить одно сравнение сделает его быстрее, поэтому первое решение должно быть лучше, но на самом деле, разветвление can be slow.И поскольку операции сравнения на самом деле очень быстрые, просто назначение результата сравнения четыре раза, скорее всего, «быстрее».

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

Я знаю, что переключатель легко победит обоих с точки зрения производительности.

Оператор switch дает вам тот же эффект, что и цепь ifs и elses, поэтому здесь нет никакой разницы.

Я думаю, что другой вопрос в этом вопросе будет состоять в том, что такое сравнения Big-O между ними?

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

+0

Это объяснение было тем, что я действительно искал. После прочтения других ответов в целом я могу решить отметить это как ответ. – gh0st

+0

@ gh0st Какой смысл понимать разницу в производительности вещей, которые делают совершенно разные вещи? Вы все равно должны делать то, что вам дает результат, который вы хотите, а не тот, который, по вашему мнению, будет работать лучше (не то, что будет какая-либо значимая разница в производительности, как говорится в ответе, поскольку различия будут слишком маленький, чтобы даже заметить). – Servy

+0

@ Серви, я понимаю, о чем вы говорите. Мне нужно выполнить некоторую отладку. – gh0st

1

Функции совершенно по-разному. Производительность не имеет значения; они не делают то же самое.

Первый фрагмент устанавливает соответствующую переменную в true, если условие выполнено, и ничего не делает, если соответствующее условие не выполняется, то есть оно оставляет исходное значение.

Второй фрагмент присваивает значение каждой переменной на каждой итерации.

Таким образом, первый фрагмент эффективно спрашивает: «любое значение, равное этому числу» для каждого из чисел, второй фрагмент эффективно спрашивает «последнее значение, равное этому числу» для каждого из чисел. Я предполагаю, что вы намереваетесь на первое, а не последнее, так что последнее просто ошибочно.

+0

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

0

Ну, в случае с integers, мне очень нравится использовать switch, когда у меня слишком много случаев. @ima объясняет это в ответ this. В противном случае это имеет значение только для того, что выглядит лучше или более «читаемым»

Однако использование switch с strings - совершенно другая история, как объясняется в сообщении this.

+0

У меня есть кое-что для чтения. Спасибо за ссылки @LuisLavieri. – gh0st