6

哪个编译成更快的代码:“ans = n * 3”或“ans = n+(n*2)”?

假设 n 是 int 或 long,并且它在现代 Win32 Intel 机器上运行。

如果涉及一些取消引用,这会有所不同,也就是说,其中哪一个会更快?

长一个;
长 *pn;
长答案;

...
*pn = some_number;
答案 = *pn * 3;

或者

答案 = *pn+(*pn*2);

或者,由于优化编译器在任何情况下都可能考虑到这一点,因此无需担心这一点吗?

4

11 回答 11

55

除非您使用一些异国情调的编译器,否则 IMO 没有必要进行此类微优化。我会把可读性放在首位。

于 2008-09-10T10:48:08.657 回答
15

没关系。现代处理器可以在一个时钟周期或更短的时间内执行整数 MUL 指令,这与需要执行一系列移位和内部加法以执行 MUL 从而使用多个周期的旧处理器不同。我敢打赌

MUL EAX,3

执行速度比

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

这种优化可能有用的最后一个处理器可能是 486。(是的,这偏向于英特尔处理器,但也可能代表其他架构)。

无论如何,任何合理的编译器都应该能够生成最小/最快的代码。所以总是首先考虑可读性。

于 2008-09-10T11:30:46.883 回答
10

自己测量很容易,为什么不这样做呢?(使用gcctime来自cygwin)

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

进行几次测试,然后重复其他情况。

如果你想偷看汇编代码,gcc -S -O2 test1.c

于 2008-09-10T11:06:09.783 回答
4

这将取决于编译器、其配置和周围的代码。

您不应该在不进行测量的情况下尝试猜测事情是否“更快”。

一般来说,你现在不应该担心这种纳米级优化的东西——它几乎总是完全无关紧要的,如果你真的在一个重要的领域工作,你已经在使用分析器并查看汇编语言输出编译器。

于 2008-09-10T10:51:54.997 回答
4

不难发现编译器对您的代码做了什么(我在这里使用的是 DevStudio 2005)。使用以下代码编写一个简单的程序:

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

在中间行放置一个断点并使用调试器运行代码。触发断点后,右键单击源文件并选择“Go To Disassembly”。您现在将看到一个显示 CPU 正在执行的代码的窗口。在这种情况下,您会注意到最后两行产生完全相同的指令,即“lea eax,[ebx+ebx*2]”(在这种特殊情况下不是位移和加法)。在现代 IA32 CPU 上,由于 CPU 的流水线性质,过早使用修改值会导致惩罚,直接执行 MUL 可能比位移更有效。

这说明了 aku 所说的内容,即编译器足够聪明,可以为您的代码选择最佳指令。

于 2008-09-10T11:45:10.390 回答
1

它确实取决于您实际使用的编译器,但很可能它们会转换为相同的代码。

您可以通过创建一个小型测试程序并检查其反汇编来自行检查。

于 2008-09-10T10:48:40.463 回答
1

大多数编译器都足够聪明,可以将整数乘法分解为一系列位移和加法。我不了解 Windows 编译器,但至少使用 gcc 你可以让它吐出汇编器,如果你看一下,你可能会看到两种编写它的方式相同的汇编器。

于 2008-09-10T10:49:33.473 回答
1

它不在乎。我认为还有更重要的事情需要优化。你花了多少时间思考和写这个问题,而不是自己编码和测试?

:-)

于 2008-11-20T01:00:08.093 回答
1

只要你使用了一个不错的优化编译器,只需编写易于编译器理解的代码。这使编译器更容易执行巧妙的优化。

你问这个问题表明优化编译器比你更了解优化。所以相信编译器。使用n * 3.

也看看这个答案

于 2008-11-20T01:15:05.770 回答
0

编译器擅长优化您的代码。任何现代编译器都会为这两种情况生成相同的代码,并另外替换* 2为左移。

于 2008-09-10T10:50:38.057 回答
0

相信你的编译器会优化这样的小段代码。可读性在代码级别更为重要。真正的优化应该在更高的层次上。

于 2008-09-15T14:09:43.887 回答