如果没有赋值,是否会更快地调用非void方法?

时间:2015-05-05 12:51:59

标签: java performance

有时当我重构我的代码时,即使我之后不使用它,也会在方法中保留return语句。我想知道这是不是一个好主意。

假设我们有一个方法:

public Date doStuff(){
     Date today = new Date();
    // some other logic
    return today;
}

并且该方法的使用从以下重构:

...
whatsToday = doStuff();
...

为:

...
doStuff();
...

如果我重构方法以返回void,那么方法本身会更快吗?

如果方法返回某个对象但没有赋值,第二次调用会更快吗?

3 个答案:

答案 0 :(得分:2)

通常,在编写Java程序时,不要过分担心微性能。这当然不是一般建议,但特别是在考虑小的潜在优化时,通常是正确的。 JVM的工作是负责分析和优化您的应用程序,尤其是您提到的优化,例如避免分配短期对象或从方法返回值。

为此,HotSpot VM(执行大多数Java应用程序)附带了一个非常强大的just-in-time compiler,它对您的代码应用了一长串优化。对于您的代码段,它通常会应用inliningescape analysis的组合。这样,它会发现您的返回值未使用,只需删除额外的分配。因此,从方法返回值的这一小细节对于程序的性能根本不重要。

如果您想了解一些额外的详细信息,请点击HotSpot适用的is a list of optimizations。您甚至可以使用JVM为您的代码生成的tools for looking at the optimized machine code

答案 1 :(得分:-1)

理想情况下,将返回类型捕获到引用变量中绝不应影响性能;我这样说是因为,jvm默认为每个要执行的事务分配一个匿名内存位置,因此仅为该位置分配一个名称不应该影响性能,但是如果你不打算使用返回的值,那么GC会清除下一次执行时的内存位置,如果为其分配名称,则只有在取消范围或设置为null时才会清除它。有更好的内存管理。所以从这个角度来看,我们可以说它的性能有所提高。

答案 2 :(得分:-1)

我写了以下测试:

class Test {
    public int test() {
        return 0;
    }
    public void foo() {
        int n = test();
    }
    public void bar() {
        test();
    }
}

,编译它然后使用javap -c Test.class

进行反汇编
class Test {
  Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int test();
    Code:
       0: iconst_0
       1: ireturn

  public void foo();
    Code:
       0: aload_0
       1: invokevirtual #2                  // Method test:()I
       4: istore_1
       5: return

  public void bar();
    Code:
       0: aload_0
       1: invokevirtual #2                  // Method test:()I
       4: pop
       5: return
}

正如您所看到的,使用返回值的foo()与忽略它的bar()之间的字节代码级别的唯一区别是(正如预期的那样)指令istore_1 vs {{1} }。

我可以猜测,这些操作之间的性能差异可能非常小。此外,如果您不使用值pop,可能会被JIT删除。否则(如果使用它)性能差异主要取决于使用此值的后续代码。