我想了解好的代码优化方法和方法。
发布于 2009-05-21 22:31:42
发布于 2009-08-30 19:20:39
对于您建议的优化类型,您应该清楚地编写代码,而不是优化它们,直到您有证据证明它们是瓶颈。
尝试这样的微优化的一个危险是,您可能会使事情变得更慢,因为编译器在很多时候比您更聪明。
拿你的“优化”:
const int windowPosX = (screenWidth * 0.5) - (windowWidth * 0.5);世界上没有认真的编译器不知道最快的除以二的方法是右移一。乘以浮点0.5实际上更昂贵,因为它需要转换为浮点和返回,并执行两个乘数(这比移位更昂贵)。
但别相信我的话。看看编译器实际做了什么。gcc 4.3.3在32位Ubuntu (-O3,-msse3,-fomit-框架-指针)上编译如下:
int posx(unsigned int screen_width, unsigned int window_width) {
return (screen_width / 2) - (window_width / 2);
}对此:
00000040 <posx>:
40: 8b 44 24 04 mov eax,DWORD PTR [esp+0x4]
44: 8b 54 24 08 mov edx,DWORD PTR [esp+0x8]
48: d1 e8 shr eax,1
4a: d1 ea shr edx,1
4c: 29 d0 sub eax,edx
4e: c3 两班(使用直接操作数)和减法。很便宜。另一方面,它编译如下:
int posx(unsigned int screen_width, unsigned int window_width) {
return (screen_width * 0.5) - (window_width * 0.5);
}对此:
00000000 <posx>:
0: 83 ec 04 sub esp,0x4
3: 31 d2 xor edx,edx
5: 8b 44 24 08 mov eax,DWORD PTR [esp+0x8]
9: 52 push edx
a: 31 d2 xor edx,edx
c: 50 push eax
d: df 2c 24 fild QWORD PTR [esp]
10: 83 c4 08 add esp,0x8
13: d8 0d 00 00 00 00 fmul DWORD PTR ds:0x0
15: R_386_32 .rodata.cst4
19: 8b 44 24 0c mov eax,DWORD PTR [esp+0xc]
1d: 52 push edx
1e: 50 push eax
1f: df 2c 24 fild QWORD PTR [esp]
22: d8 0d 04 00 00 00 fmul DWORD PTR ds:0x4
24: R_386_32 .rodata.cst4
28: de c1 faddp st(1),st
2a: db 4c 24 08 fisttp DWORD PTR [esp+0x8]
2e: 8b 44 24 08 mov eax,DWORD PTR [esp+0x8]
32: 83 c4 0c add esp,0xc
35: c3 ret您所看到的是将其转换为浮点,从数据段(可能在缓存中也可能不在缓存中)用值进行乘法,并将其转换回整数。
当您尝试执行像这样的微优化时,请考虑这个例子。这不仅为时过早,而且可能根本没有帮助(在这种情况下,它会严重伤害!)
说真的:别这么做。我认为一个金科玉律是永远不做这样的优化,除非像我在这里所做的那样定期检查编译器的输出。
发布于 2009-08-30 18:32:40
编辑这个答案最初出现在另一个问题(已经合并)中,OP列出了一些可能的优化技术,他认为这些优化技术必须有效。所有这些都严重依赖于假设(比如x << 1总是比x * 2快)。下面我试图指出这种假设的危险。
由于您的所有观点都可能是错误的,这说明了这种过早和琐碎的优化的危险。让编译器来做这样的决定,除非你非常清楚自己在做什么,而且这很重要。
否则就不重要了。
更重要的是(而不是过早的)在通用程序结构中的优化。例如,一次又一次地重新生成相同的大量数据可能非常糟糕,因为在许多地方都需要这样的数据。相反,必须在设计中考虑一些因素,以允许共享这些数据,从而只计算一次。
了解您正在工作的领域也是非常重要的。我来自生物信息学背景,在C++中做了很多核心算法的工作。我经常处理大量的数据。不过,目前我正在用Java创建一个应用程序,每次创建容器的副本时我都会畏缩不前,因为我习惯于避免这样的操作。但是对于我想象中的Java来说,这些操作是完全微不足道的,用户一点也看不出来。哦,好吧,我只是得忘掉自己。
顺便问一下:
声明常量时初始化它们(如果可以的话)…
嗯,在许多语言(例如C++)中,常量(即标记为const的标识符)必须在定义时被弱化,因此您实际上没有选择。然而,这是一个好主意遵循这一规则,不仅对常量,但在一般情况下。不过,原因不一定是表现。它只是简单得多的代码,因为它清楚地将每个标识符绑定到一个目的上,而不是让它飞来飞去。
https://stackoverflow.com/questions/895574
复制相似问题