哪一个更优或者是否有任何差异?
String s = methodThatReturnsString();
int i = methodThatReturnsInt();
thirdMethod(s, i);
或
thirdMethod(methodThatReturnsString(), methodThatReturnsInt());
通过最优,我的意思是在内存使用等方面最优。
答案 0 :(得分:15)
这与优化无关,但更多的是你的代码的可读性问题......
答案 1 :(得分:11)
哪一个更优化?
更易于阅读的内容: - )
我认为任何差异都会在编译时被优化掉(前提是之后不使用声明的变量 - 即解决方案在其他方面相同)。
答案 2 :(得分: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) {
}
}
让我们编译它:
> 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()
不同。看起来编译器正在添加调试符号。也许这迫使它明确地将返回值分配给局部变量,引入额外的指令。
让我们尝试使用 no 调试重新编译它:
> 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 ++,您可以在其中看到汇编程序 代码,它正是如此 执行)。我想你意识到了, 但我认为应该更清楚 在帖子里。
答案 3 :(得分:6)
我更喜欢第一种选择。然而,这与速度无关,但具有可调试性。在第二个选项中,我无法轻松检查s
和i
的值。在性能方面,这根本没有任何区别。
答案 4 :(得分:1)
应该没有任何区别。暂时使用的String
和int
都必须驻留在某处,Java在内部是堆栈计算机。因此,无论您是否给出该方法的返回值调用名称,都必须在执行thirdMethod(String, int)
之前将它们存储在堆栈中。
对于生成的JITted代码的含义很难找到。这是一个完全不同的ob抽象层次。
如有疑问,请说明。但我不希望这里有任何不同。
答案 5 :(得分:1)
这是一回事。在这两种情况下,将调用相同的函数并且将分配变量(自动或显式定义)。唯一的区别是,在第二种情况下,变量将准备好进行垃圾回收,而在第一种情况下,您需要等待超出范围。
当然,第一个更具可读性。
答案 6 :(得分:0)
完全没有区别。在这种情况下,您可能需要考虑可读性和清晰度。
答案 7 :(得分:0)
实验和测量。如果速度是重要的,那么测量速度。如果内存使用很重要,请测量内存使用量如果字节码指令的数量很重要,则计算字节码指令。如果代码可读性很重要,请测量代码的可读性。确定如何衡量代码可读性是你的功课。
如果你没有进行实验和测量,那么你将获得意见和论证。
或者,如果你很幸运,SO上的某个人会为你运行实验。
PS这篇文章当然是我的观点和论点
答案 8 :(得分:-2)
thirdMethod(metodThatReturnsString(),metodThatReturnsInt());
更优化......