有时当我重构我的代码时,即使我之后不使用它,也会在方法中保留return语句。我想知道这是不是一个好主意。
假设我们有一个方法:
public Date doStuff(){
Date today = new Date();
// some other logic
return today;
}
并且该方法的使用从以下重构:
...
whatsToday = doStuff();
...
为:
...
doStuff();
...
如果我重构方法以返回void
,那么方法本身会更快吗?
如果方法返回某个对象但没有赋值,第二次调用会更快吗?
答案 0 :(得分:2)
通常,在编写Java程序时,不要过分担心微性能。这当然不是一般建议,但特别是在考虑小的潜在优化时,通常是正确的。 JVM的工作是负责分析和优化您的应用程序,尤其是您提到的优化,例如避免分配短期对象或从方法返回值。
为此,HotSpot VM(执行大多数Java应用程序)附带了一个非常强大的just-in-time compiler,它对您的代码应用了一长串优化。对于您的代码段,它通常会应用inlining和escape 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删除。否则(如果使用它)性能差异主要取决于使用此值的后续代码。