静态与非静态方法

时间:2009-07-26 14:21:24

标签: c# performance

假设您在非静态类中有一些可以变为静态的方法。
例如:

private double power(double a, double b)
    {
        return (Math.Pow(a, b));
    }

您是否看到将方法签名更改为静态有什么好处?在上面的例子中:

private static double power(double a, double b)
    {
        return (Math.Pow(a, b));
    }

即使有一些性能或内存增益,编译器也不会在编译时进行简单的优化吗?

<小时/> 编辑:我正在寻找的是将方法声明为静态的好处。我知道这是常见做法。我想了解它背后的逻辑 当然,这种方法只是澄清我的意图的一个例子。

10 个答案:

答案 0 :(得分:33)

根据定义,power是无状态的,对任何封闭类没有副作用,因此应该声明static

来自MSDN的这个article涉及非静态与静态的一些性能差异。调用的速度比实例化和调用快四倍,但它确实只在紧密循环中才是一个性能瓶颈。

答案 1 :(得分:8)

如果声明方法是静态的,应该会有轻微的性能提升,因为编译器将发出call IL指令而不是callvirt

但是和其他人说的那样,无论如何它应该是静态的,因为它与特定的实例无关

答案 2 :(得分:7)

请注意,编译器甚至不太可能代表您进行更改,因为它会更改方法的签名。因此,一些精心设计的反射(如果您使用任何反射)可能会停止工作,编译器实际上无法判断是否是这种情况。

答案 3 :(得分:3)

  

您认为将方法签名更改为静态会有什么好处吗?

三个好处:

  1. 使无状态方法静态有助于记录和阐明其目的。否则,人们倾向于担心该方法所依赖的神秘状态?

  2. 可以从其他静态代码调用静态方法,因此可能更有用。

  3. 静态方法调用比实例调用具有更少的运行时开销。编译器不能自动进行转换 - 一个原因是因为它会影响null的使用。即使在方法中没有使用实例状态,也需要在空引用上调用该方法失败并使用NullReferenceException。

答案 4 :(得分:2)

对我来说,一个简单的问题就是“我是否应该只是为了调用这个函数来实例化这个对象”。在你的功能的情况下,我会说答案是否定的,所以它应该是静态的。这个方法似乎与您的对象无关,所以我再次投票静态。

答案 5 :(得分:2)

不访问实例数据或调用实例方法的成员可以标记为static(在Visual Basic中为Shared)。将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。发出非虚拟调用站点将阻止在运行时检查每个调用,以确保当前对象指针为非null。这可以为性能敏感的代码实现可测量的性能增益。在某些情况下,无法访问当前对象实例表示正确性问题。

答案 6 :(得分:1)

此方法应该是静态的,因为它与您的类或类成员无关。它只适用于此功能的输入。

也许您可能需要在不创建该类的情况下调用它。所以如果它是静态的,那就没关系,但如果不是,你就不能在没有该类的任何实例的情况下调用它。


静态方法的优点:

无需先创建对象。该方法可立即使用。

当您拥有不依赖于特定对象状态的通用功能时,这是一件好事。例如,查看Arrays类或java.util中的Collections类。

静态方法对工厂有利。将您的需求作为参数传递,获得一个全新的对象。看来不是构造者。

静态方法的缺点:

您没有对象实例,因此您只能访问静态成员和您自己的局部变量。如果你想要一个实例,你可能需要自己创建它。

您可以创建子类,但静态方法不能是抽象的,因此将实现与调用者分离起来更加困难。


(ps:我不认为编译器会优化,如果它是静态的还是不是......但不确定)

答案 7 :(得分:1)

当编译器“JIT”代码时,编译器可能会考虑内联它,因为它很短,如果它这样做,那么很可能能够优化对未使用的this参数的任何引用。但你不能依赖任何一种。

你仍然需要创建一个对象来调用它,除非你把它变成静态的,如果你因为其他原因不需要它,那么它的开销会大得多。

答案 8 :(得分:0)

我相信编译器不会将其优化为静态方法。由于不必检查指针以查看它是否在运行时为空,因此可以获得性能提升。请查看FXCop rule以供参考。

答案 9 :(得分:-5)

我希望我们需要定义静态和非静态方法之间的区别。在这里,我发布了几行简单的代码来形象化概念差异。

public class StaticVsNonStatic
{
     public string NonStaticMethod() //non-static
     {

         return "I am the Non-Static Method"; 

     }

     static public string StaticMethod() //static
     {

         return "I am Static Method";
     }

 }

现在让我们创建一个aspx页面,尝试访问类中定义的这两个方法。

 public partial class StaticVsNonStatic_StaticVsNonWorkplace : System.Web.UI.Page
 {
     protected void Page_Load(object sender, EventArgs e)
     {

        StaticVsNonStatic objStaticVsNonStatic = new StaticVsNonStatic();
        lblDisplayNS.Text = objStaticVsNonStatic.NonStaticMethod(); //Non Static 
        lblDisplayS.Text =  StaticVsNonStatic.StaticMethod();  //Static and called without object
     }
 }

谢谢,请发表评论。

最诚挚的问候,Pritom Nandy [孟加拉国]