сдвиг битов против умножения в PHP - PullRequest
21 голосов
/ 24 ноября 2011

У меня есть следующий код:

<?php
$start = 1;

$timestart = microtime(1);
for ($i = 0; $i < 1000000; $i++) {
    $result1 = $start * 4;
}
echo "\n";
echo microtime(1) - $timestart;
echo "\n";

$timestart = microtime(1);
for ($i = 0; $i < 1000000; $i++) {
    $result2 = $start << 2;
}
echo "\n";
echo microtime(1) - $timestart;
echo "\n";

Это выводит:

0.14027094841003

0.12061500549316

Я нашел в Интернете вопрос об интервью Google (который я хотел подать на разработчика, ноЯ понимаю, что не могу), и на один из вопросов был задан вопрос, как быстрее всего умножить число.Моей первой мыслью было использовать знак *, поэтому я протестировал его.

Мой вопрос: почему сдвиг бит быстрее умножения?

Ответы [ 3 ]

16 голосов
/ 24 ноября 2011

Поскольку смещение битов - это то, что компьютер все время делает аппаратно, для процессора это не составляет труда. Умножение произвольных чисел является чем-то более сложным, потому что это не обязательно может быть сделано с помощью простого сдвига битов, но требует реальной работы. Умножение маленького целого числа на 4 - это операция, идентичная сдвигу влево на 2. Но даже если компилятор / среда выполнения / ЦП оптимизирует эту операцию до сдвига в битах, некоторый код сначала должен распознать что он может быть оптимизирован таким образом, что является большей работой, чем сам простой сдвиг битов.

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

13 голосов
/ 24 ноября 2011

Поскольку сдвиг битов - это операция, которая может быть реализована непосредственно в оборудовании, в то время как в оборудовании редко выполняются операции умножения напрямую. Умножение на степень два может быть достигнуто с помощью нескольких простых логических элементов, тогда как умножение на произвольные умножения требует, по меньшей мере, нескольких умножений на степени два плюс операция добавления к себе, сложенная друг над другом (5 = 2 * 2 + 1). Я не знаю, реализует ли язык PHP конкретную операцию сдвига, используя доступные низкоуровневые вызовы, но я был бы удивлен, если бы этого не произошло.

Источник: многолетний опыт + образование в области компьютерных наук

1 голос
/ 24 ноября 2011

В процессорах Intel sandybrigde кажется, что сдвиг с немедленной стоимостью около 1 такта, в то время как умножение занимает около 3-4 циклов.По-видимому, на производительность всей программы влияет больше факторов, чем просто умножение, но этого достаточно, чтобы изменить ситуацию.Большинство компиляторов в наши дни оптимизируют умножение на константы 2 ^ n для сдвигов (авторы компиляторов любят оптимизировать ваш код :)), но, возможно, интерпретатор PHP этого не делает.

...