2010-08-08 103 views
0

我正在写一个有趣的程序,并且每次演奏都对我来说非常痛苦。 所以我想知道什么更好 - 做一个额外的“if”语句来减少一些函数调用,或者避免那些“如果”和更多funciton调用。该函数是虚方法,它覆盖IEqualityComparer的方法Equals,它只是比较两个文件的大小和散列值。 if语句比较这两个文件的大小。我认为你有这个逻辑的重点。你可以看到我正在用C#编写这个程序。所以也许任何人都可以回答我,因为这不是我第一次想知道要选什么。感谢速度更快 - if语句还是函数的调用?

+4

没有代码,你的问题非常模糊。即使有了代码,我仍然期望在不知道实际情况的情况下仍然有点模糊。 – 2010-08-08 17:42:44

+0

'关闭不是一个真正的问题'?真的吗? *卷眼睛* – 2010-08-08 19:11:41

回答

0

我的猜测是,如果一个语句是更好的,但与当今先进的编译器,你永远不能告诉。你最好的选择是尝试两种方式并比较性能。

3

您是否尝试过分析找出?你确定这些中的任何一个是你应用程序中的瓶颈吗?

+0

当然没有。在我看来,这些时刻更是瓶颈。一切安好。我无法决定选择什么。 分析工作非常巧妙。当我比较目录中的所有文件和它的子目录时,即使我改变了很多东西,也比下次它做同样的工作快40倍。所以我不能比较相同文件夹的结果=( – Mark 2010-08-08 18:39:18

+3

@Mark:如果你不知道它是否会产生任何影响,这种决定是毫无意义的! – 2010-08-08 18:51:33

1

在过去的486和更旧的日子里,当CPU处于“哑”状态时,分支逻辑(例如if())会导致管道和/或缓存刷新,这会降低速度。现在,随着现代编译器和无序分支机构预测为您洗碗碟机的CPU,这种开销很小。

的唯一正确的方法回答你的问题是:基准这两种方法,看看这是更快。

1

是由你观察到在测试或只是一个事实,即你想想浪费了几个周期的可能性实际性能的痛苦?如果是第二种情况,解决问题的唯一有效方法就是通过工作态度。

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

8
  1. 如果你真的需要这么多的表现如此糟糕,你为什么不采用汇编语言编程?

  2. 如果您仍然确定您确实需要担心这个问题,请首先检查其他优化机会,这些优化机会有更大的潜力(更好的算法可能会使数量级比任何微优化更差)。

  3. 如果优化生活狗屎了一切的,可以肯定的唯一方式是个人资料。真。无论我们中的任何人试图猜测,他们都可能会低估JIT。

  4. 不过我对这个意见:一般来说,分支预测错误可能会伤害远不止一个函数调用,因为它螺丝缓存。但是谁说它会编译成可能会导致缓存的代码?编辑:但是,因为它看起来像是比较文件内容的严格相等性,所以在长度不同的情况下短路可以节省很多时间(考虑:文件系统告诉你这个长度需要多长时间?知道,几乎没有。需要多长时间散列10 MB文件?很长,n比较)。所以如果我猜对了,那就去短路,大声喊叫。

+0

好的,我明白了你的观点。不是在优化程序,而是为了知道答案,因为“这不是我第一次想知道该选什么” – Mark 2010-08-08 18:28:46

+0

如果你看到了这个观点,那么答案是:在最清晰的代码中做什么结果并表达程序的逻辑最好;-) – delnan 2010-08-08 19:21:34

0

没有分析就很难知道。但无论哪种方式,我都可以告诉你,你的算法通常比if vs function重要得多,而通过function通常可以更容易,更快速,更安全地更换和更新实现。最终要做更多的工作来改进算法中更重要的部分。而且,再次,知道你在那里做的方式是简介

+0

好的,谢谢你们。我得到了我正在寻找的答案 - “现在人们可以真正告诉我”。这真的是我期待听到的。所以谢谢。 – Mark 2010-08-08 18:31:16

0

答案取决于一两件事:“我使用的是一个完全新空房禁地编译”

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

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

因此:编写易于理解的代码,并且作为一项附加功能,编译器在优化代码时也会变得更容易理解。

2

保留 - 如果 - 运行速度会更快。

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

0

if由于分支可能会产生成本。成本取决于在if情况下运行的代码,在else情况下运行的代码,CPU高速缓存的大小以及编译器决策。

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

因此,这个问题确实没有一般的答案。即使你进行配置文件,也没有什么可以说,即使使用程序集的二进制副本(因为抖动会不同),或者使用不同版本的.NET环境,在另一种架构上也不会有所不同(在此处“不同版本”包括服务包,热修补程序和修补程序)。