2009-12-14 117 views
3

静态方法对非静态方法的性能问题是什么?我已经读过静态方法在性能方面更好,但我想知道它们是如何更快的?如果一个方法没有使用任何实例成员,那么我们的编译器应该照顾它并将其视为静态方法。C#中的静态方法?

回答

7

编辑:埃里克评论更多关于这here,并暗示有当使用call一些时间......但请注意他的new()例如isn't guaranteed ;-p


在原来的编译器(1.1之前),编译器确实将非虚拟实例方法(没有this)视为静态;的问题是,这会导致和null检查一些奇问题,即

obj.SomeMethod(); 

没有抛出异常(obj=null和非虚拟方法SomeMethod其中没有触及this)。如果您更改了SomeMethod的实施,那么这很糟糕。当他们调查了添加显式空值检查(即空检查和静态调用)的成本后,结果与使用虚拟调用相同,因此他们这样做,这使得它更加灵活,可预测。

请注意,“不抛出异常”也是完全行为如果SomeMethod是扩展方法(静态)。

我觉得在一个点上,你可能会释​​放出IL通过静态调用调用定期实例方法,但我最后一次尝试,我得到了“哦,不,你不知道!”来自CLR的消息(此操作可能会破坏运行时的稳定性);要么他们完全阻止了这一点,要么(可能更有可能)我把自定义的IL放到了一边。

+0

我读过C++编译器这样做,为什么他们没有让C#编译器变得那么聪明? – viky 2009-12-14 07:09:23

+0

这不是关于聪明......就像我解释的那样,在执行“空检查和静态调用”与“虚拟调用”(内置空检查)之间没有任何明显差异。那么为什么有两个不同的选项要维护? – 2009-12-14 07:16:20

3

请参阅this question

下面是摘录:

一个静态调用为4〜5倍,构建每次 一次调用一个实例方法的实例更快 。 然而,我们仍然只是讨论 约几十纳秒的每次通话

+2

请注意,这是比较为每个呼叫构造一个新的实例;它不会比较一次构建实例的更常见情况,用于多次调用。 – 2009-12-14 06:18:29

+3

如果您只是*提及另一个问题的答案,为什么不直接发布链接作为评论,或投票重复? – 2009-12-14 06:24:16

+1

另外请注意,那篇文章早在2003年.CLR已经发生了很大变化。 – 2009-12-14 06:59:22

1

我怀疑,编译器将把它作为一个静态方法,虽然可以检查自己。好处不是创建实例。没有垃圾收集器担心。只有被调用的静态构造函数,如果有的话。

+0

C++编译器是否这样做,为什么不.Net(C#)编译器 – viky 2009-12-14 06:41:55

0

静态方法快,因为构造一个实例

买,如果你只创建一个实例,并保存静态成员,性能等于

他们都非常小,整体性能

所以... ....

5

是的静态调用会更快 - 在调用方法之前,您不需要创建对象的实例。 (虽然你显然不会注意到它们之间的区别)

实际上,编译器是否优化了一个方法(使实例方法是静态的)并不重要 - 除非已经实例化方法,否则不会调用实例方法已经创建了实例,对吧?

在一天结束时,您应该尝试优化代码的可维护性,而不是试图在这里或那里节省3纳秒。

+0

我希望我们的C#编译器像C++编译器一样足够聪明,可以进行这种优化。感谢您的解释! – viky 2009-12-14 07:19:11

0

是静态方法很快,但静态变量获取的内存不受GC控制,即使不需要也不会释放,所以这是一个问题。

但是比其他任何事情你都应该考虑通用性的设计,因为内存和速度已经增加了几天,但是如果你不适当地使用静态变量,你的设计可能会很糟糕。

+0

您不需要有一个静态变量来调用静态方法。他们是不同的概念。 – 2009-12-15 01:11:52