性能反模式

时间:2009-01-08 19:48:42

标签: performance anti-patterns

由于“性能原因”,我目前正在为石化而改变糟糕的不可测试和不可维护代码的客户工作。很明显,存在许多错误观念,而且理解不明白,但仅仅是盲目信仰。

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

*重新编辑:我认为将所有内容标记为密封内部(在C#中)作为过早优化。*

我想知道人们可能会注意到或遇到的其他一些性能反模式是什么?

18 个答案:

答案 0 :(得分:70)

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

    之前和之后
  • 不衡量效果 在变化之后。

收集性能数据将显示某种技术是否成功。不这样做会导致相当无用的活动,因为当任何事情都没有改变时,某人会有“感觉”性能提升。

答案 1 :(得分:29)

房间里的大象:专注于实施级别的微优化,而不是更好的算法。

答案 2 :(得分:17)

可变重复使用。

我曾经一直这样做,认为我在声明上节省了几个周期并减少了内存占用。与调试代码的方式相比,这些节省的成本微不足道,特别是如果我最终移动代码块并且关于起始值的假设发生了变化。

答案 3 :(得分:8)

想到

过早的绩效优化。我倾向于不惜一切代价避免性能优化,当我决定需要它们时,我将问题传递给我的同事几轮,试图确保我们在适当的位置进行优化......优化。

答案 4 :(得分:6)

  1. 使用#defines而不是函数来避免函数调用的惩罚。 我已经看到了代码,其中扩展的定义结果是生成巨大且非常慢的代码。当然也不可能调试。内联函数是实现此目的的方法,但也应谨慎使用它们。

  2. 我见过代码,其中独立测试已转换为可在switch语句中使用的单词中的位。切换可以非常快,但是当人们将一系列独立测试转换为位掩码并开始编写256个优化特殊情况时,他们最好有一个非常好的基准测试证明这可以带来性能提升。从维护的角度来看,这真的是一种痛苦,独立处理不同的测试会使代码变得更小,这对性能也很重要。

答案 5 :(得分:6)

使用设计模式只是为了使用它们。

答案 6 :(得分:6)

我遇到过的一个问题就是将硬件投入到严重损坏的代码中,试图使其足够快,这与Jeff Atwood在Rulas评论中提到的文章相反。我不是在谈论通过在更快的硬件上运行使用基本的,正确的算法加速使用优化算法的加速。我正在谈论当O(n log n)算法在标准库中时,使用不明显正确的自制O(n ^ 3)算法。还有手工编码例程之类的东西,因为程序员不知道标准库中有什么。那个人很沮丧。

答案 7 :(得分:4)

缺乏明确的程序结构是他们所有人最大的代码。被认为快速的复杂逻辑几乎从来都不是。

答案 8 :(得分:4)

利用您的编程语言。使用异常处理而不是if / else之类的事情只是因为在PLSnakish 1.4中它更快。你猜怎么着?有可能它根本不快,从现在起两年后维护你的代码会让你生气,因为你混淆了代码并使它运行得慢得多,因为在PLSnakish 1.8中,语言维护者修复了问题,现在如果/其他比使用异常处理技巧快10倍。使用编程语言和框架

答案 9 :(得分:4)

朱利安伯奇曾告诉我:

“是的,但运行应用程序需要多少年才能弥补开发人员花费的时间?”

他指的是每次交易期间通过优化获得的累计时间,这需要花费一定的时间来实施。

来自老圣人的明智话语......在考虑进行时髦的优化时,我经常会想到这个建议。通过考虑在当前状态下处理代码所花费的开发人员时间与用户节省的时间相比,您可以进一步扩展相同的概念。如果您愿意,您甚至可以按开发人员与用户的每小时费率计算时间。

当然,有时候无法衡量,例如,如果一个电子商务应用程序需要1秒钟才能做出响应,那么在1秒钟内,用户会感到厌倦一些小额钱。要弥补这一秒,您需要实施并维护优化代码。优化对毛利润产生积极影响,净利润产生负面影响,因此更难以平衡。你可以试试 - 有很好的统计数据。

答案 10 :(得分:4)

编写代码时不要重构或优化。在完成代码之前不要尝试优化代码是非常重要的。

答案 11 :(得分:3)

一次更改多个变量。这让我绝对疯狂!当多个事物发生变化时,如何确定变更对系统的影响?

与此相关,进行观察无法保证的更改。如果进程不受CPU限制,为什么要添加更快/更多的CPU?

答案 12 :(得分:2)

有一位前客户打电话给我,要求我就加快他们的应用程序提出任何建议。

他似乎希望我说“检查X,然后检查Y,然后检查Z”,换句话说,提供专家猜测。

我回答说你必须诊断问题。我的猜测可能比其他人的错误少,但它们仍然是错的,因此令人失望。

我认为他不理解。

答案 13 :(得分:2)

一些开发人员认为快速但不正确的解决方案有时比缓慢但正确的解决方案更可取。因此,他们将忽略生产中“永远不会发生”或“无关紧要”的各种边界条件或情况。

这绝不是一个好主意。解决方案始终需要“正确”。

您可能需要根据具体情况调整“正确”的定义。重要的是你知道/定义你想要的结果对于任何条件,并且代码给出了那些结果。

答案 14 :(得分:2)

迈克尔·杰克逊提出了两条优化绩效的规则:

  1. 不要这样做。
  2. (仅限专家)不要这样做。
  3. 如果人们担心表现,请告诉他们让它变得真实 - 什么是好表现,你如何测试呢?然后,如果您的代码没有达到他们的标准,至少它是代码编写者和应用程序用户同意的东西。

    如果人们担心重写僵化代码(例如,时间接收器)的非性能成本,那么就会显示您的估算并证明可以在计划中完成。假设它可以。

答案 15 :(得分:2)

一般解决方案

仅仅因为给定的模式/技术在一种情况下表现更好并不意味着它在另一种环境中表现更好。

.Net中的StringBuilder过度使用是这个的一个常见例子。

答案 16 :(得分:1)

在C ++ STL中使用(例如)push_back(),〜=在D等中附加到数组,当你知道数组应该提前多大并且可以预先分配它时。

答案 17 :(得分:1)

我认为超级精益代码“接近金属”比优雅领域模型更具性能是一个普遍的神话。

这显然是由DirectX的创建者/首席开发人员解决的,他在C#中重写了c ++版本并进行了大量改进。 [所需来源]