使用静态私有方法真的比实例私有方法更快/更好吗?

我要问的是这样做是否有区别:

public Something importantBlMethod(SomethingElse arg) { if (convenienceCheckMethod(arg)) { // do important BL stuff } } private boolean convenienceCheckMethod(SomethingElse arg) { // validate something } 

和这个:

 public Something importantBlMethod(SomethingElse arg) { if (convenienceCheckMethod(arg)) { // do important BL stuff } } private static boolean convenienceCheckMethod(SomethingElse arg) { // validate something } 

我实际上使用选项1,因为它对我来说似乎更自然。

那么第一种和第二种方式之间是否有样式/约定/性能差异?

谢谢,


正如我在测试中所建议的那样,在我的基准测试中,动态方法更快。

这是测试代码:

 public class Tests { private final static int ITERATIONS = 100000; public static void main(String[] args) { final long start = new Date().getTime(); final Service service = new Service(); for (int i = 0; i < ITERATIONS; i++) { service.doImportantBlStuff(new SomeDto()); } final long end = new Date().getTime(); System.out.println("diff: " + (end - start) + " millis"); } } 

这是服务代码:

 public class Service { public void doImportantBlStuff(SomeDto dto) { if (checkStuffStatic(dto)) { } // if (checkStuff(dto)) { // } } private boolean checkStuff(SomeDto dto) { System.out.println("dynamic"); return true; } private static boolean checkStuffStatic(SomeDto dto) { System.out.println("static"); return true; } } 

对于100000次迭代,动态方法通过577ms,静态615ms。

然而,这对我来说是不确定的,因为我不知道编译器何时以及何时决定优化。

这就是我想要找到的。

绩效明智:差异(如果有的话)可以忽略不计。

经验法则是如果方法不与其类的任何成员交互,则声明您的方法是静态的。

如果函数的结果不依赖于除参数之外的任何内容,则它应该是静态的。 如果它依赖于实例,请将其设为实例成员。

这不是关于表现; 这是关于语义的。 除非你每秒呼叫这个function一百万次,否则你不会注意到性能差异,即使这样,差异也不会很大。

这一切都取决于具体情况。 通常,静态方法/变量在类中声明,以便外部类可以使用它们。

如果要调用本地方法,那么通常应该使用实例方法而不是静态调用。

仅供参考,您从实例方法调用静态方法的语法是错误的。 你必须提供class级名称。

如果您的方法需要实例数据或调用其他实例方法,则它必须是实例方法。

如果函数依赖于它的参数,而没有其他静态数据,那么它也可能是一个实例方法 – 当你调用静态函数时,你将避免重复类名。

恕我直言,没有特别需要使函数static除非:

  1. 它可以从其他类(即非private )调用,和
  2. 它不引用实例变量,和
  3. 它指的是其他静态类数据

它可能,它可能不会。 代码的不同执行可能会有所不同。

如果不深入研究Hotsport代码(或非Hotspot JVM的代码),这是唯一可以知道的事情:

  • 使用invokestatic调用静态方法,该方法不需要对象引用。
  • 使用invokespecial调用实例私有方法,这需要对象引用。

这两个操作码都有一个解析实际调用方法的过程,这些过程相对类似(你可以阅读规范)。 如果不计算实际实现的指令,就不可能说哪个更快。

invokespecial将额外的值推送到堆栈上。 这样做的时间以几纳秒计算。

而且所有这一切都没有实际意义,Hotspot可以进行各种优化。 在程序运行期间,它可能不必多次执行实际的方法解析。 它可能会选择内联方法(或者可能不会),但是这个成本将再次大致相当。

据我所知 ,静态方法的绑定与非静态私有即early binding 。 。 编译器实际上在创建字节代码时将代码(静态或非静态私有)添加到代码中。

更新:刚刚通过这篇文章 。 它说实例方法绑定是dynamic所以如果方法不是non-static private话。 你的静态方法更快

我查了一下,希望它能做你想知道的,代码不会很漂亮:

 public class main { @SuppressWarnings("all") public static void main(String[] args) { main ma = new main(); int count = Integer.MAX_VALUE; long beg = (new Date()).getTime(); for (int i = 0; i < count; i++) { ma.doNothing(); } System.out.println("priv : " + new Long((new Date()).getTime() - beg).toString()); beg = (new Date()).getTime(); for (int i = 0; i < count; i++) { doNothingStatic(); } System.out.println("privstat : " + new Long((new Date()).getTime() - beg).toString()); } private void doNothing() { int i = 0; } private static void doNothingStatic() { int i = 0; } } 

结果:

priv:1774
privstat:1736

priv:1906
privstat:1783

私人:1963年
privstat:1751

priv:1782
privstat:1929年

私人:1876年
privstat:1867

它看起来不像静态 - 非静态私有方法。 我确信这些差异来自当前的机器负担。

我参与编码竞赛,我观察到,非静态方法比静态方法更快(但是最小)。 当然,这取决于您的使用情况和情况需求,但与非静态方法相比,静态方法的性能较差。 按照惯例,您可以使用静态方法来简化代码,但创建类的实例并调用该方法将提供更好的性能。