Предполагается, что вы используете это для небольшого тестирования (поэтому разница в результате не имеет значения), это зависит от контекста и того, что компилятор делает с ним, и других факторов.
Например, при компиляции с GCC 7.3 для современного x86 они абсолютно одинаковы , оба могут компилироваться в следующую последовательность:
sarx eax, edi, esi
and eax, 1
И при использовании результата для фактического принятия решения (вместо материализации логического значения) код может все же быть таким же. Очевидно, что если код будет таким же, не может быть никакой разницы в эффективности. Clang любит использовать bt
и setc
(или использовать флаг в cmov или потоке управления, когда это необходимо), но также делает то же самое для обоих фрагментов. MSVC компилирует фрагменты различными способами и, возможно, в некотором смысле «предпочитает» формулировку 1 << i
.
Реализация b & (1 << i)
буквально (что я не наблюдал ни на одном компиляторе на самом деле) требует дополнительной инструкции для загрузки константы 1 в регистр, хотя это не обязательно означает, что это займет дополнительное время ( хотя это возможно): создание 1 не зависит от всего остального, поэтому оно может выполняться впереди всего остального, а затем сдвиг не зависит от b
, поэтому он может выполняться после того, как i
готов, но до b
.