0

我正在编写一个有趣的程序,每次性能下降对我来说都是非常痛苦的。所以我想知道什么更好 - 做一个额外的“if”语句来减少函数调用的数量,或者避免那些“if”和获得更多的函数调用。该函数是虚方法,它覆盖了 IEqualityComparer 的 Equals 方法,它所做的只是比较两个文件的大小和哈希值。if 语句比较这两个文件的大小。我想你明白了这个逻辑的意义。正如你所看到的,我正在用 C# 编写这个程序。所以也许任何人都可以回答我,因为这不是我第一次想知道该选择什么。谢谢

4

9 回答 9

8
  1. 如果你真的非常需要这么多性能,为什么不用汇编语言编程呢?

  2. 如果您仍然确定绝对需要担心这一点,请首先检查具有更大潜力的其他优化机会(更好的算法可以使数量级的差异比任何微优化都大)。

  3. 如果你从其他所有东西中优化了生活的东西,唯一确定的方法就是分析。真的。无论我们中的任何人多么努力地猜测,他们都可能会低估 JIT。

  4. 我仍然对此有意见:一般来说,分支错误预测比函数调用造成的伤害要大得多,因为它会破坏缓存。但是谁说它编译成可能会破坏缓存的代码呢?编辑:但是由于您似乎在比较文件内容是否严格相等,因此在长度不同的情况下短路可以节省很多时间(考虑:文件系统需要多长时间才能告诉您长度?它可能已经知道,所以几乎没有。散列一个 10 MB 的文件需要多长时间?非常长,比较)。所以如果我猜对了,那就去短路,大声喊叫。

于 2010-08-08T17:52:13.743 回答
3

您是否尝试过分析以找出答案?您确定其中任何一个都是您的应用程序的瓶颈吗?

于 2010-08-08T17:43:43.030 回答
2

保持如果 - 它会运行得更快。

很明显,创建文件的哈希将比 if 花费更多的时间

于 2010-08-08T17:58:45.383 回答
1

在过去,在 486 和更早的日子里,当 CPU “哑”时,分支逻辑(例如if())会导致管道和/或缓存刷新,这会减慢速度。这些天来,使用现代编译器和无序分支预测为你洗碗的 CPU,这样的开销是最小的。

回答您的问题的唯一正确方法是:对两种方法进行基准测试,看看哪个更快。

于 2010-08-08T17:46:28.627 回答
1

疼痛是由您在测试时观察到的实际性能造成的,还是仅仅因为您考虑到浪费几个周期的可能性?如果是第二种情况,解决问题的唯一明智的方法是提高态度。

分支的成本很难预测,因为现代处理器使用一些非常聪明的技术来加速执行。它们存储了一些用于预测分支目标的特殊数据结构。如果预测正确,则分支非常便宜,否则非常昂贵。错误预测的比率很低,但当然不是零。我不认为你可以得到你的问题的明确答案

于 2010-08-08T17:50:52.763 回答
0

我的猜测是 if 语句更好,但是对于当今的高级编译器,您永远无法真正分辨。您最好的选择是尝试两者并比较性能。

于 2010-08-08T17:43:12.193 回答
0

没有分析真的很难知道。if但无论哪种方式,我都可以告诉你,你的算法通常比vs重要得多function,并且使用functions 通常更容易更容易、更快速、更安全地更改和更新实现,让你最终能够做到更多地改进算法中更重要的部分。而且,再一次,了解你在那里做得如何的方法是profile

于 2010-08-08T17:52:27.613 回答
0

答案取决于一件事:“我使用的是完全脑死的编译器吗”

既然你不是,答案是“没关系”。编译器和 JIT'er 会大量转换您的代码,因此实际执行的代码与您编写的代码完全不同。

例如,可以内联函数调用,消除函数调用的所有开销。

因此:编写自己易于理解的代码,作为附带的好处,当编译器优化您的代码时,它也变得更容易理解。

于 2010-08-08T17:53:42.400 回答
0

if可能会因分支而产生成本。成本取决于在 if 情况下运行的代码、在 else 情况下运行的代码、CPU 缓存的大小和编译器的决定。

由于调用函数的成本,函数调用可能会产生成本。这可以比 for 大得多,if也可以为零(因为调用是内联的——当编译器可以“看到”在编译时将调用哪个表单时,内联甚至可以发生在虚拟调用中),或者它可以是介于两者之间。

正因为如此,这个问题确实没有一般的答案。即使您进行概要分析,也没有什么可以说它在不同的体系结构上不会有所不同,即使使用程序集的二进制副本(因为抖动会不同)或使用不同版本的 .NET 环境(和这里“不同版本”包括与之相关的服务包、热修复和补丁)。

于 2010-08-08T19:08:04.990 回答