2012-03-16 3 views
104

Я склонен к «условно-синдромный синдром», что означает, что я стараюсь использовать все условия постоянно. Я редко пользуюсь тройным оператором. Например: Является ли тернарный оператор быстрее, чем условие «если»

//I like to do this: 
int a; 
if (i == 0) 
{ 
    a = 10; 
} 
else 
{ 
    a = 5; 
} 

//When I could do this: 
int a = (i == 0) ? 10:5; 

ли это вопрос, который я использую? Что быстрее? Есть ли заметные отличия в производительности? Лучше ли использовать кратчайший код, когда это возможно?

Я использую язык программирования Java.

+4

Это не имеет значения, и вы должны скорее беспокоиться о чистом коде, чем о производительности. В этом случае, я думаю, троянский оператор просто чист. –

+3

Также вы можете сделать это так: if (i == 0) a = 10; else a = 5; ' –

+11

Преждевременная оптимизация без профилирования, показывающая определенную потребность, плоха, плоха, плоха. Используйте код, который ваш будущий «я» лучше всего поймет через 6 месяцев. –

ответ

93

Имеет ли значение, что я использую?

Да! Второй - более читаемый. Вы торгуете одной строкой, которая вкратце выражает то, что вы хотите, против девяти линий эффективного беспорядка.

Который быстрее?

Ни то, ни другое.

Лучше ли использовать кратчайший код, когда это возможно?

Не «по возможности», но, по возможности, без ущерба для последствий. Более короткий код по крайней мере потенциально более читабельен, поскольку он фокусируется на соответствующей части, а не на побочных эффектах («шаблонный код»).

+1

читаемый не означает, что это важно, perse. – Jon

+0

Даже 9 строк, если я считаю правильно, потому что слишком много пробелов. –

+16

@Jon: Да, это так. Считываемость - это все, что важно, эффективно. –

8

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

30

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

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

+0

Зачем вам здесь использовать условное обозначение? Я использовал бы тернар для чистоты. – Jon

+14

@Jon: условный оператор является фактическим * именем * для того, что вы назвали тернарным оператором. Это * * тернарный оператор, поскольку он имеет 3 операнда, но его * имя * является условным оператором. –

+1

Хорошо, спасибо за разъяснение. Я думал, что вы подразумеваете явный синтаксис if-else. – Jon

0

Лучше всего использовать то, что лучше читает - есть практически любой эффект 0 разница между производительностью.

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

24

троичной Оператор Пример:

int a = (i == 0) ? 10 : 5; 

Вы не можете сделать задание с, если/иначе, как это:

// invalid: 
int a = if (i == 0) 10; else 5; 

Это хороший повод, чтобы использовать тройной оператор.Если вы не имеете назначение:

(i == 0) ? foo() : bar(); 

Условный/еще не то, что гораздо больше кода:

if (i == 0) foo(); else bar(); 

В производительности критических случаях: измерить. Измерьте его с целевой машиной, целевой JVM, с типичными данными, если есть узкое место. Остальные идут на удобочитаемость.

Embedded в контексте, короткая форма иногда бывает очень удобно:

System.out.println ("Good morning " + (p.female ? "Miss " : "Mister ") + p.getName()); 
+0

Есть еще одна причина для использования тернарного оператора - он заставляет вас обрабатывать все случаи. –

+0

@MikeDunlavey: Если вы думаете о «О, давайте не будем забывать второй случай!Давайте используем тернарный оператор, вы также можете начать писать «еще», чтобы не забыть его, если ваш мозг настолько ненадежный, чтобы забыть его за несколько секунд написания вашего заявления. –

+0

Это не просто вопрос написания «else», это то, что вы вложили в него. –

15

Да это имеет значение, но не из-за кода показателей исполнения.

Более быстрое (перфомантное) кодирование более актуально для создания циклов и объектов, чем простые синтаксические конструкции. Компилятор должен обрабатывать оптимизацию (все это будет о том же двоичном!), Поэтому ваша цель должна быть эффективной для вас-от-будущего (люди всегда являются узким местом в программном обеспечении).

Josh Bloch's "Performance Anxiety" talk on Parleys.com

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

НО, их часто можно злоупотреблять, чтобы сделать код нечитаемым (что является кардинальным грехом) = не гнездятся тернарные операторы!

Также рассмотреть будущую ремонтопригодность, если-то еще гораздо проще расширить или изменить:

int a; 
if (i != 0 && k == 7){ 
    a = 10; 
    logger.debug("debug message here"); 
}else 
    a = 3; 
    logger.debug("other debug message here"); 
} 


int a = (i != 0 && k== 7) ? 10 : 3; // density without logging nor ability to use breakpoints 

P.S. очень полный ответ stackoverflow на To ternary or not to ternary?

+1

Я не согласен с этим: он является идиоматическим и читаемым для определения условных операторов, например, особенно при тестировании нескольких случаев, как в 'return x == 1? «один»: x == 2? «два»: «много»; Здесь можно найти правильное углубление и взломать несколько строк. –

0

попытаться использовать switch case statment. , но, как правило, это не узкое место в предпочтении.

+1

Как правило, следует избегать решений, использующих блоки «switch», когда они могут быть. По своей природе «переключатель» применяется к фиксированному числу допустимых состояний. Это создает ответственность за обслуживание программного обеспечения, потому что «допустимые состояния» очень часто движутся. Например, решения, использующие классы enum, часто работают лучше и элегантнее, чем решения, основанные на блоках 'switch'. – scottb

4

Кроме того, тернарный оператор допускает форму «необязательного» параметра. Java не позволяет добавлять необязательные параметры в сигнатуры методов, но тернарный оператор позволяет легко вводить выбор по умолчанию, если для значения параметра задано значение null.

Например:

public void myMethod(int par1, String optionalPar2) { 

    String par2 = ((optionalPar2 == null) ? getDefaultString() : optionalPar2) 
      .trim() 
      .toUpperCase(getDefaultLocale()); 
} 

В приведенном выше примере, передавая null в качестве значения параметра String получает вас строковое значение по умолчанию вместо NullPointerException. Это короткий и сладкий и, я бы сказал, очень читаемый. Более того, как уже отмечалось, на уровне байтового кода действительно нет разницы между тернарным оператором и if-then-else. Как и в приведенном выше примере, решение о выборе основывается полностью на удобочитаемости.

Кроме того, эта модель позволяет сделать параметр String необязательной (если это будет сочтено полезным сделать это), перегружая метод следующим образом:

public void myMethod(int par1) { 
    return myMethod(par1, null); 
} 
2

Для примера, приведенного, я предпочитаю троичной или оператора условия (?) по определенной причине: я ясно вижу, что назначение a не является обязательным.С помощью простого примера, это не слишком трудно сканировать, если-нибудь блок, чтобы увидеть, что a назначается в каждом пункте, но представьте себе несколько заданий в каждом пункте:

if (i == 0) 
{ 
    a = 10; 
    b = 6; 
    c = 3; 
} 
else 
{ 
    a = 5; 
    b = 4; 
    d = 1; 
} 

a = (i == 0) ? 10 : 5; 
b = (i == 0) ? 6 : 4; 
c = (i == 0) ? 3 : 9; 
d = (i == 0) ? 12 : 1; 

Я предпочитаю последний, так что вы знаете, что не пропустили задание.

Смежные вопросы