21

I have the following code:

<?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";

This outputs:

0.14027094841003

0.12061500549316

I found on the Internet a Google interview question (which I wanted to apply for a developer, but I realize I can't), and one of the questions asked what the fastest way was to multiply a number. My first thought was to use the * sign, so I tested it.

My question is, why is shifting bits faster than multiplication?

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
aki
  • 1,241
  • 2
  • 13
  • 43
  • 3
    Because multiply requires...a multiplication...which requires more time than a bitshift, because it is a more complicated operation? – Dan Nov 24 '11 at 02:24
  • 1
    @Dan - The question may have more to do with why bitshifting may or may not be equivalent to integer/float multiplication in PHP. – Jared Farrish Nov 24 '11 at 02:26
  • 1
    See http://en.wikipedia.org/wiki/Multiplication_algorithm#Electronic_usage stating that `To multiply two numbers with n digits using this method, one needs about n2 operations. More formally: using a natural size metric of number of digits, the time complexity of multiplying two n-digit numbers using long multiplication is Θ(n2).` Bit shifts are a single instruction. – drew010 Nov 24 '11 at 02:31
  • 2
    Incidentally, there are [more ways to perform multiplication than one might expect](http://en.wikipedia.org/wiki/Multiplication_algorithm) -- and different methods excel in different situations. – sarnold Nov 24 '11 at 02:31
  • @drew010; A [linear-time algorithm is available](http://en.wikipedia.org/wiki/Multiplication_algorithm#Linear_time_multiplication) -- assuming you've got the RAM for some tables. – sarnold Nov 24 '11 at 02:32
  • why did my comment get removed? i don't understand what was going on and i want to know? – Drewdin Nov 24 '11 at 04:02

3 Answers3

16

Because bit shifting is something the computer does all the time in hardware, it's a no-brainer for the CPU. Multiplying arbitrary numbers is something more difficult, because it can't necessarily be done using simple bit shifting but requires actual work. Multiplying a small integer by 4 happens to be an operation that's identical to a left-shift by 2. But even if the compiler/runtime/CPU optimizes this operation down to a bit shift, some code first needs to recognize that it can be optimized this way, which is more work than a simple bit shift itself.

Either way, it's simply more work because the two operations do entirely different things, even if the outcome of certain operations is the same.

deceze
  • 510,633
  • 85
  • 743
  • 889
13

Because a bit shift is an operation that can be implemented directly in hardware, whereas hardware rarely has multiplication operations implemented directly. Multiplication by a power of two can be achieved with a few simple logic gates, whereas multiplication by arbitrary multiplicands requires at the very least several multiplications by powers of two plus an add-to-self operation stacked on top of each other (5 = 2 * 2 + 1). I don't know if the PHP language specifically implements a shift operation by using whatever low-level calls are available, but I would be surprised if it doesn't.

Source: years of experience + computer science education

taz
  • 1,506
  • 3
  • 15
  • 26
  • You might want to make it clear that you're talking about hardware efficiency versus ISA. Both x86 and ARM support multiplication instructions in hardware. That hardly counts as "rarely". I think you need to define what you mean by "directly". – Will Bickford Nov 24 '11 at 02:50
  • I did not know that x86 and ARM support multiplication instructions in hardware. By "directly in hardware" I meant logic gates constructed in hardware, without any assembly code to assist. For example, addition and incrementation can be implemented using only hardware. I was taught that pure hardware multiplication could require thousands more gates than addition and is rarely implemented in anything but a supercomputer. Assembly routines can emulate hardware multiplication via repeated addition or other optimizations such as repeated bitshifts and addition-to-self. – taz Nov 24 '11 at 03:22
  • 1
    @taz: When you have a billion transistors in a chip, a few thousand for a multiplier isn't much, and the performance gain over shift-and-add is enough to justify it. Hard to find 32 or 64 bits CPUs that don't have multiply and divide built in. – Ira Baxter Jun 01 '12 at 19:32
  • @IraBaxter Thanks for the info. I suspect my instructor may have been a little behind the times. – taz Jun 01 '12 at 19:40
1

On Intel sandybrigde CPUs it seems a shift with immediate costs about 1 clock cycle while a multiplication takes about 3-4 cycles. Apparently the whole program performance is affected by more factors than just the raw multiplication but it is enough of making a difference. Most compilers these days optimize multiplication by constants 2^n to shifts (compiler writers love to optimize your code :)) but maybe the PHP interpreter doesn't.

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
  • This was a good answer. Now I'm curious if the PHP interpreter optimizes 2^n multiplies to shifts! – aeu Nov 18 '15 at 17:59