【问题标题】:Static Vs Instance Method Performance C#静态与实例方法性能 C#
【发布时间】:2011-03-02 07:07:45
【问题描述】:

我的 ASP.NET Web 应用程序的公共类中声明的全局方法很少。

我习惯在公共类中声明所有全局方法,格式如下

public static string MethodName(parameters) { }

我想知道它对性能的影响?

  1. 哪个更好?静态方法还是非静态方法?
  2. 为什么它更好?

http://bytes.com/topic/c-sharp/answers/231701-static-vs-non-static-function-performance#post947244 状态:

因为,静态方法使用锁是线程安全的。总是 在内部执行 Monitor.Enter() 和 Monitor.exit() 以确保 线程安全。

http://dotnetperls.com/static-method 声明:

在调用堆栈上调用静态方法通常比调用更快 实例方法。在 C# 中有几个原因 编程语言。实例方法实际上使用'this' 实例指针作为第一个参数,所以实例方法将 总是有那个开销。实例方法也用 中间语言中的 callvirt 指令,它强加了一个 轻微的开销。请注意,将您的方法更改为静态 方法不太可能对雄心勃勃的绩效目标有很大帮助,但是 它可以提供一点帮助,并可能导致进一步减少。

我有点困惑该使用哪一个?

【问题讨论】:

  • 您是否阅读到第一个链接的末尾?很明显,即使在线程中,关于自动锁定的断言也是错误的。

标签: c# .net performance static-methods


【解决方案1】:

您的第一个链接表明:

那是因为静态方法正在使用 锁是线程安全的。总是做 内部有一个 Monitor.Enter() 和 Monitor.exit() 确保线程安全

这完全是,可怕的,可恶的错误。


如果将[MethodImpl(MethodImplOptions.Synchronized)] 添加到方法中,则该语句部分正确。

添加此属性将导致 CLR 将 static 方法包装在 lock(typeof(YourClass)) 中,并将实例方法包装在 lock(this) 中。

This should be avoided where possible


您的第二个链接是正确的。
Static methods are a little bit faster than instance methods,因为它们没有 this 参数(因此跳过了 callvirt 指令中的 NullReferenceException 检查)

【讨论】:

    【解决方案2】:

    我往往不太关心这方面的表现。静态方法真正有用的是执行功能实践。例如,如果您在实例类中创建了一个私有静态辅助方法,您就会知道该方法不能修改实例的状态。

    【讨论】:

      【解决方案3】:

      我个人总是会选择更适合完成当前任务并编写稳定、可读且易于维护的代码的方法。

      还有其他方法可以提高应用程序的性能。

      一些例子:

      • 如果您想多次使用简单方法而不每次都实例化一个对象(辅助函数),请在静态类中使用静态方法。

      • 如果您的方法访问类中的其他变量并且不是线程安全的,请使用 s 成员函数。

      • 在 asp.net 中,如果您想跨会话共享对象,或者您可以使用内部缓存结果的方法来提高性能,那么静态方法也可以。

      • 您可以混合使用这两种方式并使用工厂设计模式来创建具有一些成员函数的类,但要确保一次始终只有一个实例。

      • 有时静态函数可以避免愚蠢的错误或减少额外运行时检查的需要:

        String.IsNullOrEmpty(thisstringisnull)  // returns true
        thisstringisnull.IsNullOrEmpty() // If Microsoft would have implemented
                                         // the method this way you would get a
                                         // NullReferenceException
        

      但总的来说,这完全取决于当前的任务。您的问题没有简单的“始终使用这种方法......”的答案。

      【讨论】:

      • 感谢 SchlaWiener 的回答。我声明了多次使用的实用方法,并且从可维护的方法来看很好,但是我对一个线程中提到的方法锁定感到困惑。
      • 实际上,您现在可以拥有使用空值的扩展方法,因此 thisstringisnull.IsNullOrEmpty() 可能有意义。
      • @SWeko:真的吗?不知道那件事。对于每个扩展方法都是这样吗?或者如果我编写扩展方法,我需要添加一些额外的代码?
      • 嗯,扩展方法只是语法糖,除了调用站点的外观,第一个参数没有什么特别之处。所以是的,这适用于任何扩展方法。
      【解决方案4】:

      这基本上是一种设计选择。如果您有包括创建类实例和更新某些属性的逻辑,请选择实例方法,因为静态方法将在实例之间共享。如果你有一些实用功能,比如做一些字符串操作,创建一个连接字符串等等。不涉及对象操作,去静态方法。

      【讨论】:

        猜你喜欢
        • 2012-08-30
        • 2012-03-28
        • 1970-01-01
        • 2012-11-12
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        相关资源
        最近更新 更多