性能反模式

14

我目前正在为一位客户工作,他们因“性能原因”而害怕更改低劣的、无法测试和难以维护的代码。很明显,有许多误解流传,并且这些原因仅仅是盲目信从,而非真正理解。

我遇到的一个这样的反模式是需要将尽可能多的类标记为sealed internal...

*重新编辑:我认为在C#中将所有东西标记为sealed internal是一种过早的优化。

我想知道人们可能意识到或遇到的其他性能反模式有哪些?


你应该详细说明为什么将类标记为 internal 是一种反模式?这是因为你认为它们应该是私有的还是公共的,还是因为在 C# 中不指定任何内容会默认为 internal? - casperOne
这不仅仅是关于性能问题,更多的是糟糕的开发流程。 - dkretz
在性能的名义下执行的操作。 :) - Kev
@casperOne..谢谢,我已经添加了一个内部说明注释。 - Xian
@Xian:我猜你的意思是“将类的成员标记为内部”。如果您不将它们公开(唯一的其他选择),则类已默认为内部。 - P Daddy
@PDaddy - 实际上我是指密封内部,谢谢您的及时回复,我已经添加了另一个编辑。干杯 - Xian
18个回答

71

我遇到的最大性能反模式是:

  • 在更改前后不进行性能测量。

收集性能数据将显示某种技术是否成功。不这样做将导致相当无用的活动,因为有人会“感觉”性能提高了,但实际上什么都没变。


29

房间里的大象:将注意力集中于实现层面的微观优化,而非更好的算法。


17

变量重用。

我曾经总是这样做,认为在声明上节省了几个周期并降低了内存占用。与代码调试时的混乱相比,这种节省微不足道,尤其是当我移动代码块并且关于起始值的假设发生改变时。


2
任何值得一试的编译器都会为这两个变量使用相同的内存位置或寄存器,就像您重用一个变量时一样(因为它们的生命周期显然不重叠)。 - rmeador
1
没错。而且,如果你使用的是非编译语言,语言本身的开销可能会再次超过好处。但是谁知道呢?Sebastian的答案是找出答案的唯一方法。 :) - Kev

8

过早的性能优化让人想起来。我倾向于尽可能避免性能优化,当我决定需要它们时,我会将问题传递给我的同事们,经过几轮尝试,确保我们将混淆...嗯,优化放在正确的位置。


你“倾向于不惜一切代价避免性能优化”?这似乎有点极端,而且你似乎把难以阅读的代码等同于优化,这是不正确的。尽管过早地进行优化是不好的,但你回答的其余部分与你的标题无关。 - hhafez
1
我并不完全认同“过早优化是万恶之源”的说法。我认为真正的问题在于你应该只关注那些需要优化的东西;很容易陷入优化那些很少被调用或者实际上并没有太大差别的例程中而浪费时间。但是,在设计整体架构时考虑代码性能仍然非常重要,因为这可能会产生影响。 - thomasrutter
我确实会考虑性能。在这种情况下,优化更多地意味着“牺牲其他方面”,以便挤出更多的性能。特别是如果那个“其他方面”是“代码清晰度”,我就会进入“不惜一切代价避免”的模式。当我需要在性能祭坛上进行牺牲时,“为清晰度进行优化”会对我很有帮助。 - PEZ

6

我曾经遇到过的一个问题是,在一些严重有问题的代码上投入硬件资源,试图让它变快,这有点像Jeff Atwood在Rulas评论中提到的相反情况。我不是在谈论使用更快的硬件来加速使用基本正确算法的排序与使用优化算法之间的差异。我所说的是,当标准库中存在O(n log n)算法时,使用一个不明显正确的自制O(n^3)算法。还有一些手写例程的事情,因为程序员不知道标准库里有什么。这种情况非常令人沮丧。


不应该通过向糟糕设计的数据库添加硬件来解决问题,而是应该重新设计它。 - HLGEM

6

仅仅为了使用设计模式而使用它们。


6
  1. 使用#define代替函数来避免函数调用的惩罚。我曾经看到过一些代码,其中宏定义的扩展生成了巨大而且非常缓慢的代码。当然,这也是不可能进行调试的。内联函数是解决这个问题的方法,但是也要小心使用。

  2. 我曾经看到过一些代码,其中独立测试被转换为一个字中的位,可以在switch语句中使用。Switch语句可以非常快速,但是当人们将一系列独立测试转换为位掩码并开始编写一些256个优化特殊情况时,他们最好有一个很好的基准证明这会带来性能提升。从维护的角度来看,这真的很麻烦,并且将不同的测试视为独立的使得代码更小,这对于性能也很重要。


4
缺乏明确的程序结构是所有代码中最大的罪恶。被认为快速的复杂逻辑几乎从来不会真正快。

4
Exploiting your programming language. 例如,仅仅因为在PLSnakish 1.4中使用异常处理而不是if/else,就认为它更快。猜猜看?很可能根本没有更快,两年后维护你的代码的人会对你非常生气,因为你混淆了代码并使其运行速度变慢,因为在PLSnakish 1.8中,语言维护者修复了这个问题,现在if/else比使用异常处理技巧快10倍。与你的编程语言和框架一起工作!

谢谢。太遗憾了,它已经消失了。我对那个作品有点自豪。=) - PEZ

4

在编写代码时不要重构或优化。 在完成代码之前,不要试图优化你的代码,这一点非常重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接