Если заявление в C ++ - PullRequest
       3

Если заявление в C ++

5 голосов
/ 02 февраля 2010

Сено, дорогой!

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

Теперь мы можем делать все, используя оператор if в c ++, так что это очень мощный оператор с точки зрения программирования, но дорогой с точки зрения времени компьютера.

Я начинающий, и я изучаю курс структуры данных после введения в курс C ++. мой вопрос к тебе
Лучше ли мне использовать выражение ifsivivly?

Ответы [ 10 ]

17 голосов
/ 02 февраля 2010

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

В общем, да, они могут быть дорогими. Нет, тебе вообще не стоит об этом беспокоиться. Но Николай поднимает отдельную (хотя и в равной степени обоснованную) точку зрения. Полиморфный код часто предпочтительнее (для удобства обслуживания), чем утверждения if или case

13 голосов
/ 02 февраля 2010

Я не уверен, как вы можете обобщить, что оператор if стоит дорого.

Если у вас есть

if ( true ) { ... }

тогда этот if наиболее вероятно будет оптимизирован вашим компилятором.

Если, с другой стороны, у вас есть ..

if ( veryConvolutedMethodTogGetAnswer() ) { .. }

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

«если» сами по себе обычно не «дороги» с точки зрения тактов.

7 голосов
/ 02 февраля 2010

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

Если операторы могут быть дорогими, потому что они заставляют компилятор генерировать инструкции ветвления. Если вы сможете найти способ кодировать ту же логику таким образом, чтобы компилятору вообще не приходилось разветвляться, код, вероятно, будет намного быстрее, даже если будет больше общих инструкций. Я помню, как невероятно удивился тому, как перекодирование короткого фрагмента кода с использованием различных битовых манипуляций, а не ветвлений ускорило его на 10-20%.

Но это не повод избегать их вообще. Это просто то, что нужно иметь в виду, когда вы пытаетесь выжать последнюю часть скорости из фрагмента кода, который, как вы знаете, критичен к производительности, потому что вы уже запустили профилировщик и различные другие инструменты, чтобы доказать это себе. *

Другая причина, по которой операторы могут быть дорогими, заключается в том, что они могут усложнить вашу программу, что затруднит ее чтение и обслуживание. Сохраняйте сложность ваших индивидуальных функций на низком уровне. Не используйте слишком много операторов, которые создают различные пути управления через вашу функцию.

5 голосов
/ 02 февраля 2010

Я бы сказал, много if statement дорого с точки зрения ремонтопригодности.

2 голосов
/ 02 февраля 2010

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

В качестве примера, подсчет, сколько раз условие выполнено (например, сколько чисел в векторе больше 10000):

for (std::vector<int>::const_iterator it = v.begin(), end = v.end(); it != end; ++it) {
    //if (*it > 10000) ++count; 
    count += *it > 10000;
}

Версия, которая просто добавляет 1 или 0 к итоговой сумме, может быть немного быстрее (я попробовал набрать 100 миллионов чисел, прежде чем смог различить разницу).

Однако в MinGW 3.4.5 использование выделенного стандартного алгоритма оказывается заметно быстрее:

count = std::count_if(v.begin(), v.end(), std::bind2nd(std::greater<int>(), 10000));

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

Другое место, где вы часто можете избежать оценки сложных условий, - это использование справочных таблиц (эмпирическое правило: алгоритмы часто можно сделать быстрее, если вы позволите им использовать больше памяти). Например, подсчет гласных (aeiou) в списке слов, где вы можете избежать разветвления и оценки нескольких условий:

unsigned char letters[256] = {0};
letters['a'] = letters['e'] = letters['i'] = letters['o'] = letters['u'] = 1; 

for (std::vector<std::string>::const_iterator it = words.begin(), end = words.end(); it != end; ++it) {
    for (std::string::const_iterator w_it = it->begin(), w_end = it->end(); w_it != w_end; ++w_it) {
        unsigned char c = *w_it;
        /*if (c == 'e' || c == 'a' || c == 'i' || c == 'o' || c == 'u') {
            ++count;
        }*/
        count += letters[c];
    }
} 
1 голос
/ 02 февраля 2010

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

Возможно, ваш инструктор имел в виду, что вам следует избегать чего-то подобного:

if (i == 0) {
    ...
} else if (i == 1) {
    ...
} else if (i == 2) {
    ...
} ...

В этом случае может быть более логичным переосмыслить структуру данных и / или алгоритм или, по крайней мере, использовать switch/case:

switch (i) {
    case 1: ...; break;
    case 2: ...; break;
    ...;
    default: ...; break;
}

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

Краткий ответ: используйте if тогда и только тогда, когда это имеет смысл!

0 голосов
/ 03 января 2013

Я сталкивался с проблемами производительности из-за многих операторов if, вызываемых внутри циклов в пакетных сценариях, поэтому вместо этого я использовал целочисленную математику для эмуляции оператора if, и это значительно улучшило производительность.

    if [%var1%] gtr [1543]
        set var=1
    else
        set var=0

эквивалентно

    set /a var=%var1%/1543

Я даже использовал гораздо более длинные выражения со многими операциями / и%, и это все же было предпочтительнее оператора if.

Я знаю, что это не C ++, но я думаю, это тот же принцип. Поэтому, когда вам нужна производительность, избегайте условных выражений столько, сколько сможете.

0 голосов
/ 02 февраля 2010

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

FOR EACH i IN container
  IF i < 100
    i = 100
  container.NEXT(i)
END FOR

производительность больше всего определяется container.NEXT(i); это гораздо дороже для связанных списков, чем для смежных массивов. Для связанных списков это требует дополнительного доступа к памяти, который в зависимости от кеша может занять от 2,5 нс до 250 нс. Стоимость оператора if будет измеряться в долях наносекунды.

0 голосов
/ 02 февраля 2010

Вы можете использовать Switch вместо, что делает более читабельным, но я не буду, если это будет быстрее. Если у вас есть что-то вроде:

if (condition1) {
   // do something
} else if (condition2) {
   // do something
} else if (condition3) { 
   // do something
} else if (condition4) { 
   // do something
}

Я не то, что можно сделать, чтобы ускорить это. если condition4 встречается чаще, вы можете переместить его наверх.

0 голосов
/ 02 февраля 2010

С точки зрения компьютерного времени оператор «если» сам по себе является одним из самых дешевых операторов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...