PHP中的移位位与乘法

PHP中的移位位与乘法,php,bit-shift,multiplication,Php,Bit Shift,Multiplication,我有以下代码: <?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++) { $r

我有以下代码:

<?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
我在互联网上发现了一个谷歌面试问题(我想申请一个开发者,但我意识到我不能),其中一个问题是问什么最快的方法是乘法。我的第一个想法是使用
*
符号,所以我测试了它

0.14027094841003

0.12061500549316

我的问题是,为什么位移位比乘法快?

因为位移位是计算机在硬件上一直在做的事情,CPU不用动脑筋就可以做到。将任意数字相乘是更困难的事情,因为它不一定使用简单的位移位来完成,而是需要实际的工作。将一个小整数乘以4恰好是一个与左移位乘以2相同的操作。但是,即使编译器/运行时/CPU将此操作优化为一个位移位,一些代码首先需要认识到它可以通过这种方式进行优化,这比简单的位移位本身要复杂得多

0.14027094841003

0.12061500549316

无论哪种方式,这都只是更多的工作,因为这两种操作做的事情完全不同,即使某些操作的结果是相同的。

因为位移位是一种可以直接在硬件中实现的操作,而硬件很少直接实现乘法操作。二次幂的乘法可以通过几个简单的逻辑门实现,而任意乘法的乘法至少需要几次二次幂的乘法加上一个叠加在彼此之上的加法自运算(5=2*2+1)。我不知道PHP语言是否通过使用任何可用的低级调用来具体实现移位操作,但如果没有,我会感到惊讶

0.14027094841003

0.12061500549316

资料来源:多年的经验+计算机科学教育

在英特尔sandybrigde CPU上,这似乎是一种转换,即时成本约为1个时钟周期,而乘法大约需要3-4个周期。显然,整个程序的性能受更多因素的影响,而不仅仅是原始乘法,但这足以产生影响。现在大多数编译器都会通过常数2^n到移位来优化乘法(编译器编写者喜欢优化代码:),但PHP解释器可能不会这样做。

因为乘法需要…乘法…这比位移位需要更多的时间,因为这是一个更复杂的运算?@Dan-问题可能更多地涉及到为什么在PHP中,位移位可能或可能不等同于整数/浮点乘法。请参见说明
要使用此方法将两个数字与n个数字相乘,需要进行n2次运算。更正式地说:使用位数的自然大小度量,使用长乘法将两个n位数相乘的时间复杂度为Θ(n2)。
位移位是一条指令。顺便说一句,在不同的情况下,有--和不同的方法。@drew010;A--假设你有一些表的RAM。你可能想清楚地表明你在谈论硬件效率和ISA。x86和ARM在硬件上都支持乘法指令。这几乎算不上“很少”。我认为您需要定义“直接”的含义。我不知道x86和ARM在硬件中支持乘法指令。所谓“直接在硬件中”,我指的是在硬件中构造的逻辑门,没有任何汇编代码来辅助。例如,添加和增量只能使用硬件实现。有人告诉我,纯硬件乘法可能比加法需要数千个门,而且除了超级计算机之外,很少在任何东西上实现。汇编例程可以通过重复加法或其他优化(如重复位移位和自我加法)来模拟硬件乘法。@taz:当一个芯片中有10亿个晶体管时,乘法器的几千个晶体管并不多,通过移位和加法获得的性能增益足以证明这一点。很难找到没有内置乘法和除法的32位或64位CPU。@IraBaxter感谢您提供的信息。我怀疑我的老师可能有点落后于时代。这是一个很好的答案。现在我很好奇PHP解释器是否会将2^n的倍数优化为移位!
0.14027094841003

0.12061500549316