这两段代码中的哪一块更好/更快/使用更少的内存?

vrm*_*vrm 1 java optimization

哪一个更优或者有什么不同?

String s = methodThatReturnsString();
int i = methodThatReturnsInt();
thirdMethod(s, i);
Run Code Online (Sandbox Code Playgroud)

要么

thirdMethod(methodThatReturnsString(), methodThatReturnsInt());
Run Code Online (Sandbox Code Playgroud)

通过最优,我的意思是在内存使用等方面最优.

Rom*_*las 15

它与优化无关,但更多的是代码的可读性问题......

  • 绝对,但请记住,人们可能不同意第一个或第二个是否更具可读性. (2认同)

jen*_*ram 11

哪一个更优化?

一个更容易阅读:-)

我认为编译时任何差异都会被优化掉(前提是之后不使用声明的变量 - 即解决方案在其他方面是相同的).


Ada*_*ter 10

我非常怀疑这两种形式都是相同的,但不要相信我的意思.让我们发现自己!:d

public class Tests {

    public void test1() {
        String s = methodThatReturnsString();
        int i = methodThatReturnsInt();
        thirdMethod(s, i);
    }

    public void test2() {
        thirdMethod(methodThatReturnsString(), methodThatReturnsInt());
    }

    public String methodThatReturnsString() {
        return "";
    }

    public int methodThatReturnsInt() {
        return 0;
    }

    public void thirdMethod(String s, int i) {

    }

}
Run Code Online (Sandbox Code Playgroud)

我们来编译它:

> javac -version
javac 1.6.0_17

> javac Tests.java

现在,让我们打印出字节码指令!

> javap -c Tests
Compiled from "Tests.java"
public class Tests extends java.lang.Object{
public Tests();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public void test1();
  Code:
   0:   aload_0
   1:   invokevirtual   #2; //Method methodThatReturnsString:()Ljava/lang/String;
   4:   astore_1
   5:   aload_0
   6:   invokevirtual   #3; //Method methodThatReturnsInt:()I
   9:   istore_2
   10:  aload_0
   11:  aload_1
   12:  iload_2
   13:  invokevirtual   #4; //Method thirdMethod:(Ljava/lang/String;I)V
   16:  return

public void test2();
  Code:
   0:   aload_0
   1:   aload_0
   2:   invokevirtual   #2; //Method methodThatReturnsString:()Ljava/lang/String;
   5:   aload_0
   6:   invokevirtual   #3; //Method methodThatReturnsInt:()I
   9:   invokevirtual   #4; //Method thirdMethod:(Ljava/lang/String;I)V
   12:  return

public java.lang.String methodThatReturnsString();
  Code:
   0:   ldc     #5; //String
   2:   areturn

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

public void thirdMethod(java.lang.String, int);
  Code:
   0:   return

}

我觉得这看起来有点奇怪 - test1()而且test2()有所不同.看起来编译器正在添加调试符号.也许这迫使它明确地将返回值分配给局部变量,引入了额外的指令.

让我们尝试重新编译它而不需要调试:

> javac -g:none Tests.java
> javap -c Tests
public class Tests extends java.lang.Object{
public Tests();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public void test1();
  Code:
   0:   aload_0
   1:   invokevirtual   #2; //Method methodThatReturnsString:()Ljava/lang/String;
   4:   astore_1
   5:   aload_0
   6:   invokevirtual   #3; //Method methodThatReturnsInt:()I
   9:   istore_2
   10:  aload_0
   11:  aload_1
   12:  iload_2
   13:  invokevirtual   #4; //Method thirdMethod:(Ljava/lang/String;I)V
   16:  return

public void test2();
  Code:
   0:   aload_0
   1:   aload_0
   2:   invokevirtual   #2; //Method methodThatReturnsString:()Ljava/lang/String;
   5:   aload_0
   6:   invokevirtual   #3; //Method methodThatReturnsInt:()I
   9:   invokevirtual   #4; //Method thirdMethod:(Ljava/lang/String;I)V
   12:  return

public java.lang.String methodThatReturnsString();
  Code:
   0:   ldc     #5; //String
   2:   areturn

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

public void thirdMethod(java.lang.String, int);
  Code:
   0:   return

}

不可思议!

因此,根据我的编译器(Sun JDK),第二个版本的字节码更短.但是,虚拟机可能会优化任何差异.:)

编辑:一些额外的澄清礼貌Joachim Sauer的评论:

重要的是要注意字节代码只讲述故事的一半:它实际执行的方式在很大程度上取决于JVM(这与C/C++完全不同,在C/C++中你可以看到汇编程序代码,它正是它的执行方式).我认为你意识到这一点,但我认为应该在帖子中更清楚.

  • 重要的是要注意字节代码只讲述故事的一半:它实际执行的方式在很大程度上取决于JVM(这与C/C++完全不同,在C/C++中你可以看到汇编程序代码,它正是它的执行方式).我认为你意识到这一点,但我认为应该在帖子中更清楚. (2认同)
  • ++花时间来完成它.我唯一没有听到的是有人说差异的*相关性*取决于功能内部的工作量.对于典型功能,您发现的差异很容易出现在噪音中. (2认同)

Tho*_*zer 6

我更喜欢第一种选择.然而,这与速度无关,但具有可调试性.在第二个选项中,我无法轻易检查s和的值是什么i.在性能方面,这根本没有任何区别.