首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪些是好的代码优化方法?

哪些是好的代码优化方法?
EN

Stack Overflow用户
提问于 2009-05-21 22:28:07
回答 20查看 4.6K关注 0票数 5

我想了解好的代码优化方法和方法。

  1. 如果我已经在考虑性能,如何避免过早地进行优化。
  2. 如何找到代码中的瓶颈?
  3. 如何确保随着时间的推移,我的程序不会变得更慢?
  4. 要避免哪些常见的性能错误(例如,我知道在try{} catch{}块的catch部分中返回在某些语言中是不好的
EN

回答 20

Stack Overflow用户

回答已采纳

发布于 2009-05-21 22:31:42

  1. 不要考虑性能,要考虑清楚性和正确性。
  2. 用侧写器。
  3. 继续使用分析器。
  4. 见1。
票数 27
EN

Stack Overflow用户

发布于 2009-08-30 19:20:39

对于您建议的优化类型,您应该清楚地编写代码,而不是优化它们,直到您有证据证明它们是瓶颈。

尝试这样的微优化的一个危险是,您可能会使事情变得更慢,因为编译器在很多时候比您更聪明。

拿你的“优化”:

代码语言:javascript
复制
const int windowPosX = (screenWidth * 0.5) - (windowWidth * 0.5);

世界上没有认真的编译器不知道最快的除以二的方法是右移一。乘以浮点0.5实际上更昂贵,因为它需要转换为浮点和返回,并执行两个乘数(这比移位更昂贵)。

但别相信我的话。看看编译器实际做了什么。gcc 4.3.3在32位Ubuntu (-O3,-msse3,-fomit-框架-指针)上编译如下:

代码语言:javascript
复制
int posx(unsigned int screen_width, unsigned int window_width) {
  return (screen_width / 2) - (window_width / 2);
}

对此:

代码语言:javascript
复制
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    

两班(使用直接操作数)和减法。很便宜。另一方面,它编译如下:

代码语言:javascript
复制
int posx(unsigned int screen_width, unsigned int window_width) {
  return (screen_width * 0.5) - (window_width * 0.5);
}

对此:

代码语言:javascript
复制
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

您所看到的是将其转换为浮点,从数据段(可能在缓存中也可能不在缓存中)用值进行乘法,并将其转换回整数。

当您尝试执行像这样的微优化时,请考虑这个例子。这不仅为时过早,而且可能根本没有帮助(在这种情况下,它会严重伤害!)

说真的:别这么做。我认为一个金科玉律是永远不做这样的优化,除非像我在这里所做的那样定期检查编译器的输出。

票数 40
EN

Stack Overflow用户

发布于 2009-08-30 18:32:40

编辑这个答案最初出现在另一个问题(已经合并)中,OP列出了一些可能的优化技术,他认为这些优化技术必须有效。所有这些都严重依赖于假设(比如x << 1总是比x * 2快)。下面我试图指出这种假设的危险。

由于您的所有观点都可能是错误的,这说明了这种过早和琐碎的优化的危险。让编译器来做这样的决定,除非你非常清楚自己在做什么,而且这很重要。

否则就不重要了。

更重要的是(而不是过早的)在通用程序结构中的优化。例如,一次又一次地重新生成相同的大量数据可能非常糟糕,因为在许多地方都需要这样的数据。相反,必须在设计中考虑一些因素,以允许共享这些数据,从而只计算一次。

了解您正在工作的领域也是非常重要的。我来自生物信息学背景,在C++中做了很多核心算法的工作。我经常处理大量的数据。不过,目前我正在用Java创建一个应用程序,每次创建容器的副本时我都会畏缩不前,因为我习惯于避免这样的操作。但是对于我想象中的Java来说,这些操作是完全微不足道的,用户一点也看不出来。哦,好吧,我只是得忘掉自己。

顺便问一下:

声明常量时初始化它们(如果可以的话)…

嗯,在许多语言(例如C++)中,常量(即标记为const的标识符)必须在定义时被弱化,因此您实际上没有选择。然而,这是一个好主意遵循这一规则,不仅对常量,但在一般情况下。不过,原因不一定是表现。它只是简单得多的代码,因为它清楚地将每个标识符绑定到一个目的上,而不是让它飞来飞去。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/895574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档