假设您在非静态类中有一些可以变为静态的方法。
例如:
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));
}
即使有一些性能或内存增益,编译器也不会在编译时进行简单的优化吗?
<小时/> 编辑:我正在寻找的是将方法声明为静态的好处。我知道这是常见做法。我想了解它背后的逻辑 当然,这种方法只是澄清我的意图的一个例子。
答案 0 :(得分:33)
根据定义,power
是无状态的,对任何封闭类没有副作用,因此应该声明static
。
来自MSDN的这个article涉及非静态与静态的一些性能差异。调用的速度比实例化和调用快四倍,但它确实只在紧密循环中才是一个性能瓶颈。
答案 1 :(得分:8)
如果声明方法是静态的,应该会有轻微的性能提升,因为编译器将发出call
IL指令而不是callvirt
。
但是和其他人说的那样,无论如何它应该是静态的,因为它与特定的实例无关
答案 2 :(得分:7)
请注意,编译器甚至不太可能代表您进行更改,因为它会更改方法的签名。因此,一些精心设计的反射(如果您使用任何反射)可能会停止工作,编译器实际上无法判断是否是这种情况。
答案 3 :(得分: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 [孟加拉国]