Что быстрее (маска >> i & 1) или (маска & 1 << i)? - PullRequest
0 голосов
/ 25 марта 2011

В моем коде я должен выбрать одно из этих двух выражений (где маска и я не постоянные целые числа -1 < i < (sizeof(int) << 3) + 1). Я не думаю, что это сделает выполнение моей программы лучше или хуже, но это очень интересно для меня. Вы знаете, что лучше и почему?

Ответы [ 8 ]

5 голосов
/ 25 марта 2011

Прежде всего, когда вы обнаружите, что спрашиваете «что быстрее», ваша первая реакция должна состоять в том, чтобы оценить, измерить и выяснить для себя.

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

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

3 голосов
/ 25 марта 2011

C выражения не могут быть «быстрее» или «медленнее», потому что ЦП не может оценивать их напрямую.

Какой из них «быстрее», зависит от машинного кода, который ваш компилятор сможет сгенерировать для этих двух выражений.Если ваш компилятор достаточно умен, чтобы понять, что в вашем контексте оба делают одно и то же (например, вы просто сравниваете результат с нулем), он, вероятно, сгенерирует один и тот же код для обоих вариантов, что означает, что они будут одинаково быстрыми.В таком случае вполне возможно, что сгенерированный машинный код даже отдаленно не будет напоминать последовательность операций в исходном выражении (т. Е. Без сдвига и / или без побитового и).Если то, что вы пытаетесь сделать здесь, это просто проверить значение одного бита, то есть другие способы сделать это, кроме комбинации сдвиг-и-бит-по-и.И многие из этих «других способов» не могут быть выражены в C. Вы не можете использовать их в C, в то время как компилятор может использовать их в машинном коде.

Например, процессор x86 имеет выделенный битовыйтестовая инструкция BT, которая извлекает значение определенного бита по его номеру.Таким образом, умный компилятор может просто сгенерировать что-то вроде

MOV eax, i
BT  mask, eax
...

для обоих ваших выражений (при условии, что это более эффективно, в чем я не уверен).

3 голосов
/ 25 марта 2011

Используйте любой из них, и пусть ваш компилятор оптимизирует его так, как ему нравится.

2 голосов
/ 25 марта 2011

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

2 голосов
/ 25 марта 2011

Если «i» является константой времени компиляции, то вторая будет выполнять меньше команд - 1 << i будет вычислено во время компиляцииИначе я бы предположил, что они были бы такими же. </p>

1 голос
/ 25 марта 2011

Вряд ли так будет быстрее.Если вам действительно любопытно, скомпилируйте простую программу, которая выполняет и то, и другое, разберите и посмотрите, какие инструкции сгенерированы.

Вот как это сделать:

gcc -O0 -g main.c -o main
objdump -d main | less
0 голосов
/ 25 марта 2011

2 выражения не являются логически эквивалентными, производительность не является вашей заботой!

Если производительность была вашей заботой, напишите цикл, чтобы сделать 10 миллионов каждого и измерить.

РЕДАКТИРОВАТЬ: Вы отредактировали вопрос после моего ответа ... поэтому, пожалуйста, игнорируйте мой ответ, поскольку ограничения меняют положение.

0 голосов
/ 25 марта 2011

Вы можете проверить вывод сборки, а затем посмотреть, сколько тактов занимает каждая инструкция.

Но в 99,99999999 процентах программ это не имеет большого значения.

...