在这个网站上已经有很多性能问题了,但是在我看来,几乎所有的问题都是非常具体的,而且相当狭窄。几乎所有人都重复了避免过早优化的建议。

我们假设:

代码已经正常工作了 所选择的算法对于问题的环境已经是最优的 对代码进行了测量,并隔离了有问题的例程 所有优化的尝试也将被衡量,以确保它们不会使事情变得更糟

我在这里寻找的是策略和技巧,在一个关键算法中,当没有其他事情可做,但无论如何都要挤出最后百分之几。

理想情况下,尽量让答案与语言无关,并在适用的情况下指出所建议的策略的任何缺点。

我将添加一个带有我自己最初建议的回复,并期待Stack Overflow社区能想到的任何其他东西。


当前回答

在带有模板的语言(c++ /D)中,您可以尝试通过模板参数传播常量值。你甚至可以用开关来处理小的非常值集合。

Foo(i, j); // i always in 0-4.

就变成了

switch(i)
{
    case 0: Foo<0>(j); break;
    case 1: Foo<1>(j); break;
    case 2: Foo<2>(j); break;
    case 3: Foo<3>(j); break;
    case 4: Foo<4>(j); break;
}

缺点是缓存压力,因此这只会在深度或长期运行的调用树中获得,其中值在持续时间内是恒定的。

其他回答

以下是我使用的一些快速而粗糙的优化技术。我认为这是“第一关”优化。

了解时间都花在了什么地方。是文件IO吗?是CPU时间吗?是因为网络吗?是数据库吗?如果IO不是瓶颈,优化IO是没有用的。

了解您的环境了解在哪里进行优化通常取决于开发环境。例如,在VB6中,通过引用传递比通过值传递慢,但是在C和c++中,通过引用传递要快得多。在C语言中,如果返回代码表明失败,尝试一些东西并做一些不同的事情是合理的,而在Dot Net中,捕获异常比尝试前检查有效条件要慢得多。

在频繁查询的数据库字段上构建索引。你几乎总是可以用空间来换取速度。

在要优化的循环内部,我避免了必须进行任何查找。找到循环外的偏移量和/或索引,并重用循环内的数据。

最小化IO尝试以一种减少必须读或写的次数的方式进行设计,特别是在网络连接上

减少抽象代码必须通过的抽象层越多,它就越慢。在关键循环内部,减少抽象(例如,揭示避免额外代码的低级方法)

对于带有用户界面的项目,生成一个新线程来执行较慢的任务使应用程序感觉反应更快,尽管不是。

你通常可以用空间来换取速度。如果有计算或其他密集的操作,看看是否可以在进入关键循环之前预先计算一些信息。

不像之前的答案那么深入或复杂,但下面是: (这些更多是初级/中级水平)

明显:干 向后运行循环,所以总是与0比较,而不是与变量比较 尽可能使用位操作符 将重复的代码分解为模块/函数 缓存对象 局部变量具有轻微的性能优势 尽可能限制字符串操作

你知道吗,一根CAT6电缆能够比缺省的Cat5e UTP电缆更好地屏蔽外部干扰10倍?

对于任何非离线项目,尽管拥有最好的软件和硬件,但如果你的throughoutput很弱,那么这条细线就会挤压数据并给你带来延迟,尽管只有几毫秒……

此外,CAT6电缆的最大吞吐量更高,因为您实际上更有可能收到铜芯电缆,而不是CCA,铜芯包覆铝,这通常出现在所有标准CAT5e电缆中。

如果您面临丢包,丢包,那么提高24/7操作的吞吐量可靠性可以使您所寻找的不同。

对于那些追求家庭/办公室连接可靠性的人来说(并且愿意对今年的快餐店说不,在年底你可以在那里),以知名品牌的CAT7电缆的形式为自己提供LAN连接的顶峰。

最后几个%是一个非常CPU和应用程序依赖的东西....

缓存架构不同,有些芯片有片上内存 你可以直接映射,ARM的(有时)有一个矢量 单位,SH4是一个有用的矩阵操作码。有GPU吗 也许一个着色器是可行的。TMS320非常 对循环中的分支敏感(因此分离循环和 如果可能的话,将条件移到室外)。

名单在....上但这类事情真的是 最后的手段……

编译x86,并运行Valgrind/Cachegrind对代码 进行适当的性能分析。或者德州仪器的 CCStudio有一个贴心的侧写器。然后你就知道在哪里了 关注……

向它扔更多的硬件!