2013-09-23 3 views
6

У меня есть цикл while, внутри которого я хочу выполнить определенную операцию только один раз, и другую операцию для всех остальных циклов.C/C++ сравнение только один раз

while (..) { 
    if (0 == count) { 
     // do_this 
    } else { 
     // do_that 
    } 
    count++; 
} 

Здесь count потребности в сравнении с 0 только один раз, но это излишне сравнивается в каждом прогоне цикла. Есть ли альтернативный способ, когда сравнение происходит только один раз, а однажды преуспел, снова не называется?

+0

Вы уверены, что уместность удара? Перезапись кода без 'if()' block _might_ будет быстрее, но насколько это понятно для разработчиков, как сейчас? –

+0

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

ответ

18

Либо сделать вещь для count == 0 перед циклом, или, если это невозможно (потому что в середине других вещей, которые осуществляются) просто написать код, чтобы быть читаемым человеком и любой наполовину достойный компилятор найдет для вас это. Или это не будет выяснено, а предсказатель ветвления в CPU выполнит эту работу. В любом случае национал-оптимизация, как это, скорее всего, будет стоить вам больше времени на чтение кода, чем вы когда-либо сохраните во время выполнения.

+3

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

8
{ 
    // do_this 
} 
count = 1; /*assuming count previously started at zero*/ 
while (..) { 
    // do_that 
    count++; /*although some folk prefer ++count as it's never slower than count++*/ 
} 

лучше

+0

Вы должны деформировать что-либо с if (...) statememt, иначе это не то же самое. – Arpegius

+0

Арпеджиус: действительно, вы делаете; '// делать это' должно быть в фигурных скобках. Я изменил ответ. – Bathsheba

+0

спасибо, это круто. Но он не будет выглядеть чистым, если у меня есть цикл while с 'getline', например. когда я читаю файл и хочу выполнить некоторую операцию только для первой строки файла. В этом случае с вашей схемой мне нужно будет дважды вызвать 'getline' дважды в' do_this' и в другое время в 'while (..)' – user13107

3

Не оптимизируйте излишне!

Стоимость сравнения составляет 1-2 такта, и, как упоминалось в Art, его можно было бы оптимизировать компилятором. Стоимость абсолютно пренебрежимо мала по сравнению со стоимостью чтения из файла. Производительность вашей программы будет в любом случае связана с I/O (чтение или чтение диска в зависимости от того, отображается ли файл в памяти).

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

+1

В то время как стоимость сравнения небольшая, стоимость ветки обычно довольно большая.Разумеется, не в порядке ввода-вывода, но в критическом для производительности фрагменте кода вы не * * * не хотите останавливать конвейер. – Angew

+0

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

+0

@Art Да, ты сказал это в своем ответе, и я дал тебе +1 за это. Но этот ответ не упоминает об этом: кажется, что «даже если он не оптимизирован, сравнение составляет всего 1-2 такта». Не говоря, почему это супер-оптимально для предсказания ветвей, это звучит опасно для меня. – Angew

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