Java 如果没有赋值,对非void方法的调用是否更快?

Java 如果没有赋值,对非void方法的调用是否更快?,java,performance,Java,Performance,有时,当我重构代码时,我会将return语句留在方法中,即使之后我没有使用它。我想知道这是不是个好主意 假设我们有一个方法: public Date doStuff(){ Date today = new Date(); // some other logic return today; } 该方法的使用从以下方面进行重构: ... whatsToday = doStuff(); ... 致: 如果我重构方法以返回void,方法本身会更快吗 如果方法返回某个对象但没

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

假设我们有一个方法:

public Date doStuff(){
     Date today = new Date();
    // some other logic
    return today;
}
该方法的使用从以下方面进行重构:

...
whatsToday = doStuff();
...
致:

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


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

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

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

出于这个目的,(大多数Java应用程序都是用它来执行的)附带了一个非常强大的工具,它在代码上应用了一长行优化。对于您的代码段,它通常会应用和的组合。这样,它会发现您的返回值未使用,只需删除额外的分配。因此,从方法返回值的这一小细节对程序的性能根本不重要


如果你想知道一些额外的细节,这里的热点适用。您甚至可以使用JVM为您的代码生成的代码。

我编写了以下测试:

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
}
类测试{
Test();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
公共int测试();
代码:
0:iconst_0
1:我轮到你了
公开无效foo();
代码:
0:aload_0
1:invokevirtual#2//方法测试:()I
4:istore_1
5:返回
公共空白栏();
代码:
0:aload_0
1:invokevirtual#2//方法测试:()I
4:流行音乐
5:返回
}
正如您所看到的,使用返回值的
foo()
和忽略返回值的
bar()
之间字节码级别的唯一区别是(正如预期的那样)指令
istore\u 1
vs
pop


我可以猜测,这两种操作在性能上可能有非常小的差异。此外,如果不使用值
istore\u 1
,则可能会被JIT删除。否则(如果您使用它),性能的差异将主要取决于使用此值的后续代码

考虑到您只是返回指针,速度差应该可以忽略不计。但我们将看看是否有人对此进行了分析。还有一些需要考虑的问题:如果您的类不是唯一调用该方法的类,而是使用返回的对象,而您突然将其转换为不带returntype的方法,该怎么办?不相关。真正的性能来自别处,没有考虑方法返回类型。非常同意。我不认为这在性能方面会有任何明显的区别。字节码只是一种相当高的抽象,用于向JVM描述程序,“更少的字节码”根本不会导致“更快的代码”。JIT编译器会做各种事情来提高程序的效率,性能在很大程度上取决于上下文、运行时概要文件和应用的优化。此外,如果JIT编译器“识别”一个模式,更多的字节代码有时甚至会导致更高性能的代码。@RafaelWinterhalter,我在上一段提到过这一点。然而,字节码通常有助于理解幕后发生的事情。不幸的是,没有。字节码并没有真正公开比Java源代码更多的信息。这仅仅是一个翻译,没有应用接近零的优化。而且JIT编译是相当复杂的。生成的机器代码是执行内容的唯一可靠来源(在特定的配置文件中,在特定的机器和操作系统上)。
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
}