В Godbolt Compiler Explorer вы можете увидеть, что различные компиляторы делают с обеими версиями, а также «вариант 3» KamilCuk.
Угадайте, что: например, с помощью g * Компилятор cc на x86-64 и оптимизация - все они выдают точно такой же код. Так что это не имеет никакого значения.
(В частности, все они используют инструкцию условного набора, которая не требует перехода, является ли условие истинным или ложным.)
Это типично: современные компиляторы достаточно умны, чтобы видеть, что все они эквивалентны, и генерировать лучший код независимо от того, каким образом вы его написали. Так что думать о таких вещах - пустая трата времени. Если кому-то, читающему программу, какой-то способ кажется более понятным, сделайте это так. Если вы не думаете, что это имеет какое-либо значение для человека, просто выберите путь и продолжайте.
Если у вас есть основания полагать, что один случай более распространен, чем другой, вы можете использовать что-то вроде g cc __builtin_expect
, чтобы намекнуть это компилятору. Таким образом, если есть возможность оптимизировать одну ветвь так, чтобы она была быстрее другой, компилятор сделает это для более общей. Также могут быть способы использовать профилирование для измерения того, какая ветвь используется чаще, и автоматически информировать об этом компилятор. Но компилятор обычно не будет пытаться сделать такие выводы только из вашего выбора, какая ветвь является «тогда», а какая «остальной».
Однако в этом случае использование __builtin_expect
не делает Это ничего не меняет, поэтому обе ветви уже оптимизированы так, как это хорошо знает компилятор, и он не знает, как сделать одну из них быстрее, даже за счет замедления другой.