【发布时间】:2019-07-21 01:54:33
【问题描述】:
这是我第二次提出这个问题,因为它是第一次被标记为重复,但这次我在其中进行了某些修改,但没有得到答案。
现在我正在优化代码,我看到了很多代码,我们在其中创建了一个新变量然后进行初始化,如下面示例代码中的第一个循环所示:Code example
BigInteger limit = new BigInteger("10000");
long l = System.currentTimeMillis();
for (BigInteger i = BigInteger.ONE; i.compareTo(limit) < 0; i =
i.add(BigInteger.ONE))
{
BigDecimal temp = new BigDecimal(0);
}
long l1 = System.currentTimeMillis();
//After modification
BigDecimal temp1;
for (BigInteger i = BigInteger.ONE; i.compareTo(limit) < 0; i =
i.add(BigInteger.ONE))
{
temp1 = new BigDecimal(0);
}
long l2 = System.currentTimeMillis();
System.out.println("1st loop time: "+(l1-l)/1000.0);
System.out.println("2nd loop time: "+(l2-l1)/1000.0);
然后在第二个中,我进行了一些修改,如图所示。我的问题看起来都很熟悉,只是变量范围不同,但第一个循环需要很多时间。
好吧,正如某些人所说,使用修改后的代码,但后来我做了另一个这样的实验:Code example
BigInteger limit = new BigInteger("10000");
long l = System.currentTimeMillis();
BigDecimal temp1;
for (BigInteger i = BigInteger.ONE; i.compareTo(limit) < 0; i = i.add(BigInteger.ONE))
{
temp1 = new BigDecimal(0);
}
long l1 = System.currentTimeMillis();
for (BigInteger i = BigInteger.ONE; i.compareTo(limit) < 0; i = i.add(BigInteger.ONE))
{
BigDecimal temp = new BigDecimal(0);
}
long l2 = System.currentTimeMillis();
System.out.println("1st loop time: "+(l1-l)/1000.0);
System.out.println("2nd loop time: "+(l2-l1)/1000.0);
与第二个相比,第一个循环需要更多时间。但是人们说第一个更好,或者有人说第二个更好,但我不这么认为。提供一些示例,以便我了解哪个是最好的以及为什么会这样。
【问题讨论】:
-
在哪些方面更好?在性能方面,我认为第一个循环更好,因为您不会在每个循环中删除/创建新变量。在逻辑/安全性方面,第二个更好,因为你的 temp 变量确实是 temp 并且不会在循环之间(以及 for 循环之外)持续存在
-
好吧,你说第一个更好。如果我将第一个循环移动到第二个循环,然后将第二个循环移动到第一个循环,如图所示,第一个循环需要很长时间。 JIT 中是否有任何魔力,因为每个第一个循环都需要很长时间。
-
我没有说是,我说我认为是。但它需要被验证,而且,证明是或不是。但是看看你的测试结果,以及你在评论中添加的内容,我会说你的测试没有给出可利用的结果。差异太小而无法提供信息,如果循环的位置改变了结果,则意味着发生了其他事情,而不仅仅是创建/删除变量。编译器可能会优化一些东西。
-
如果这纯粹是理论上的,为了研究,使用更长的循环并比较字节码而不是代码可能会很有趣。如果这是一个具体项目的需要。您要么不关心这么小的差异,然后最好选择 logi/safe 循环。或者如果您关心这种差异,您最好选择其他语言而不是 Java,这样您可以更好地控制如何优化系统使用
-
是的,但我必须使用 java 弄清楚为什么会这样。
标签: java memory operating-system resources