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

Java 这两段代码中哪一段更好/更快/使用更少的内存?,java,optimization,Java,Optimization,哪一个比较理想,或者有什么区别 String s = methodThatReturnsString(); int i = methodThatReturnsInt(); thirdMethod(s, i); 或 我所说的优化是指内存使用等方面的优化。这里与优化无关,但更多的是代码的可读性问题…这里与优化无关,但更多的是代码的可读性问题…根本没有区别。在这种情况下,您可能需要考虑可读性和清晰度。 < P>根本没有区别。在这种情况下,您可能需要考虑可读性和清晰度。 哪一个更理想 一个更容易阅读的

哪一个比较理想,或者有什么区别

String s = methodThatReturnsString();
int i = methodThatReturnsInt();
thirdMethod(s, i);


我所说的优化是指内存使用等方面的优化。

这里与优化无关,但更多的是代码的可读性问题…

这里与优化无关,但更多的是代码的可读性问题…

根本没有区别。在这种情况下,您可能需要考虑可读性和清晰度。

< P>根本没有区别。在这种情况下,您可能需要考虑可读性和清晰度。

哪一个更理想

一个更容易阅读的:-

我认为在编译时,只要声明的变量在编译后不被使用,任何差异都会被优化掉,也就是说,解决方案在其他方面是相同的

哪一个更理想

一个更容易阅读的:-


我认为在编译时,只要声明的变量以后不使用,任何差异都会被优化掉,即解决方案在其他方面是相同的。

ThirdMethodMetodHattReturnsString,MetodHattReturnsIn


更为优化…

第三种方法是返回字符串,即返回字符串


更优化…

应该没有任何区别。临时使用的字符串和int都必须驻留在某个地方,Java在内部是一个堆栈机器。因此,无论您是否给出该方法调用名的返回值,它们都必须在执行thirdMethodString int之前存储在堆栈上

这对于生成的JITted代码的影响可能很难找到。这是一个完全不同的抽象层次


如有疑问,请提供个人资料。但我不希望这里有什么不同。

不应该有任何不同。临时使用的字符串和int都必须驻留在某个地方,Java在内部是一个堆栈机器。因此,无论您是否给出该方法调用名的返回值,它们都必须在执行thirdMethodString int之前存储在堆栈上

这对于生成的JITted代码的影响可能很难找到。这是一个完全不同的抽象层次


如有疑问,请提供个人资料。但我不希望这里有什么不同。

这是一样的。在这两种情况下,将调用相同的函数,并分配自动或显式定义的变量。唯一的区别是,在第二种情况下,变量将准备进行垃圾收集,而在第一种情况下,您需要等待退出范围


当然,第一个更具可读性。

也是一样。在这两种情况下,将调用相同的函数,并分配自动或显式定义的变量。唯一的区别是,在第二种情况下,变量将准备进行垃圾收集,而在第一种情况下,您需要等待退出范围


当然,第一个选项更具可读性。

我更喜欢第一个选项。然而,这与速度无关,而是与可调试性有关。在第二个选项中,我无法轻松检查s和I的值。就性能而言,这根本不会有任何区别。

我更喜欢第一个选项。然而,这与速度无关,而是与可调试性有关。在第二个选项中,我无法轻松检查s和I的值。就性能而言,这根本不会有任何区别。

我高度怀疑这两种形式是相同的,但不要相信我的话。让我们了解自己吧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 不可思议

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

编辑:约阿希姆·绍尔的评论提供了一些额外的澄清:


需要注意的是,字节 代码只讲述了故事的一半:它是如何做到的 是否实际执行在很大程度上取决于 与JVM完全不同的JVM C/C++,在这里可以看到汇编程序 代码和它的确切方式 执行。我想你已经意识到了, 但我认为应该说得更清楚 在岗位上


我高度怀疑这两种形式是相同的,但不要相信我的话。让我们了解自己吧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 不可思议

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

编辑:约阿希姆·绍尔的评论提供了一些额外的澄清:


需要注意的是,字节 代码只讲述了故事的一半:它是如何做到的 是否实际执行在很大程度上取决于 与JVM完全不同的JVM C/C++,在这里可以看到汇编程序 代码和它的确切方式 执行。我想你已经意识到了, 但我认为应该说得更清楚 在岗位上


实验和测量。如果速度很重要,那么测量速度。如果内存使用情况很重要,请测量内存使用情况。若字节码指令的数量很重要,那个么计算字节码指令的数量。如果代码可读性很重要,请测量代码可读性。弄清楚如何衡量代码可读性是你的家庭作业

如果你不进行实验和测量,你得到的将是意见和争论

或者,如果你很幸运,SO上的某个人会帮你做实验


PS当然,这篇文章是我的观点和论点

实验和测量。如果速度很重要,那么测量速度。如果内存使用情况很重要,请测量内存使用情况。若字节码指令的数量很重要,那个么计算字节码指令的数量。如果代码可读性很重要,请测量代码可读性。弄清楚如何衡量代码可读性是你的家庭作业

如果你不进行实验和测量,你得到的将是意见和争论

或者,如果你很幸运,SO上的某个人会帮你做实验



PS当然,这篇文章是我的观点和论据

如果有差异,就不值得担心。并且说差异取决于使用的编译器。编译器优化甚至可能会产生完全相同的代码,如果在此之后既不使用s也不使用i。我会根据可读性来做决定。你可以试着编译这两种代码并首先比较字节码,optimal不是一个或多或少都可以的属性。要么某些东西是最优的,要么不是。而不是更优化,你似乎意味着更好或更高效。第二,不要在程序中拼错名字;这始终是一种方法。很难想象还有比这更微不足道的性能问题。作为一名Java程序员,我要强调的是,区分这些明显等效的结构不是您的工作。如果存在差异,就不值得费心了。并且说,差异将取决于所使用的编译器。编译器优化甚至可能会产生完全相同的代码,如果在此之后既不使用s也不使用i。我会根据可读性来做决定。你可以试着编译这两种代码并首先比较字节码,optimal不是一个或多或少都可以的属性。要么某些东西是最优的,要么不是。而不是更优化,你似乎意味着更好或更高效。第二,不要在程序中拼错名字;这始终是一种方法。很难想象还有比这更微不足道的性能问题。作为一名Java程序员,我要特别强调的是,区分这些明显等效的结构并不是你的工作。当然,但请记住,人们可能不同意第一个还是第二个更具可读性。是的,你是对的。然而,这仍然是一个可读性问题;当然可以,但请记住,人们可能不同意第一个或第二个更具可读性。是的,你是对的。然而,这仍然是一个可读性问题;您可以在同一个程序中使用两个变量s和i,以便将来在同一个程序中使用两个变量s和i。需要注意的是,字节码只说明了一半的情况:它的实际执行方式在很大程度上取决于JVM,而JVM与C/C++截然不同,在那里你可以看到汇编代码和它的执行方式。我想你已经意识到了这一点,但我认为应该在帖子中说得更清楚。@Joachim:我完全同意!我已经在答案中添加了您的评论。+++感谢您花时间仔细阅读。我唯一没有听到的是有人说差异的相关性取决于函数内部进行了多少工作。对于典型的函数,您很容易发现不同之处在于噪声。需要注意的是,字节码只说明了一半的情况:它的实际执行方式在很大程度上取决于JVM,而JVM与C/C++有很大的不同,在JVM中,您可以看到汇编程序代码,而它正是如何执行的。我想你已经意识到了这一点,但我认为应该在帖子中说得更清楚。@Joachim:我完全同意!我已经在答案中添加了您的评论。+++感谢您花时间仔细阅读。我唯一没有听到的是有人说差异的相关性取决于函数内部进行了多少工作。对于典型的函数,您很容易发现的区别在于噪声。-1关于GC的断言是不正确的。实际上,在方法退出之前,不会收集任何内容。使用新的openJDKYes,但在第一个版本中,即使在方法退出后,变量s和i也不会被垃圾回收。将发生什么取决于包装代码。-1关于GC的断言不正确。实际上,在方法退出之前,不会收集任何内容。使用新的openJDKYes,但在第一个版本中,即使在方法退出后,变量s和i也不会被垃圾回收。W 将发生什么取决于包装代码。 > 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 }