为什么在Java中,循环内的声明似乎比循环外的声明更快?
当我检查时,我简直不敢相信,所以我测试了一下,似乎是真的。循环内的声明似乎比循环外的声明要快。有人能解释这是为什么吗 以下是我的测试代码:为什么在Java中,循环内的声明似乎比循环外的声明更快?,java,Java,当我检查时,我简直不敢相信,所以我测试了一下,似乎是真的。循环内的声明似乎比循环外的声明要快。有人能解释这是为什么吗 以下是我的测试代码: public class CycleTest { /** * @param args the command line arguments */ public static void main(String[] args) { long iterations = 1000000; warm
public class CycleTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
long iterations = 1000000;
warmUp(iterations);
System.out.println("Cycle1");
double individualTime = getAverageTimePerIterationc1(iterations);
iterations = 1000;
double totalTime = getTotalTimec1(iterations);
System.out.println("ns/iteration: " + individualTime);
System.out.println("Total time for " + iterations + " runs: " + totalTime);
System.out.println("Cycle2");
iterations = 1000000;
double individualTime1 = getAverageTimePerIterationc2(iterations);
iterations = 1000;
double totalTime1 = getTotalTimec2(iterations);
System.out.println("ns/iteration: " + individualTime1);
System.out.println("Total time for " + iterations + " runs: " + totalTime1);
}
public static void warmUp(long iterations) {
System.out.println("Starting warmup");
for (int i = 0; i < iterations; i++) {
runCycles();
runCycles1();
}
}
public static double getAverageTimePerIterationc1(long iterations) {
// test
System.out.println("Starting individual time test");
long timeTaken = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
runCycles();
timeTaken += System.nanoTime() - startTime;
}
return (double) timeTaken / iterations;
}
public static long getTotalTimec1(long iterations) {
// test
System.out.println("Starting total time test");
long timeTaken = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
runCycles();
timeTaken += System.nanoTime() - startTime;
}
return timeTaken;
}
public static double getAverageTimePerIterationc2(long iterations) {
// test
System.out.println("Starting individual time test");
long timeTaken = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
runCycles1();
timeTaken += System.nanoTime() - startTime;
}
return (double) timeTaken / iterations;
}
public static long getTotalTimec2(long iterations) {
// test
System.out.println("Starting total time test");
long timeTaken = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
runCycles1();
timeTaken += System.nanoTime() - startTime;
}
return timeTaken;
}
private static void runCycles() {
double intermediateResult;
for (int i = 0; i < 1000; i++) {
intermediateResult = i;
intermediateResult += 1;
}
}
private static void runCycles1() {
for (int i = 0; i < 1000; i++) {
double intermediateResult = i;
intermediateResult += 1;
}
}
}
公共类循环测试{
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
长迭代次数=1000000次;
预热(迭代);
系统输出打印项次(“循环1”);
double individualTime=GetAverageTimePacificationC1(迭代次数);
迭代次数=1000次;
double totalTime=getTotalTimec1(迭代);
System.out.println(“ns/迭代:+individualTime”);
System.out.println(“运行“+iterations+”的总时间:“+totalTime”);
System.out.println(“Cycle2”);
迭代次数=1000000次;
double individualTime1=GetAverageTimePacificationC2(迭代);
迭代次数=1000次;
double totalTime1=getTotalTimec2(迭代);
System.out.println(“ns/迭代:+individualTime1);
System.out.println(“运行“+iterations+”的总时间:“+totalTime1”);
}
公共静态无效预热(长迭代){
System.out.println(“开始预热”);
对于(int i=0;i
额外的新信息:我已经在JDK 1.6.0_27上的Windows机器上运行了它。它们生成相同的代码。这两种方法:
private static void runCycles1() {
double intermediateResult;
for (int i = 0; i < 1000; i++) {
intermediateResult = i;
}
}
private static void runCycles2() {
for (int i = 0; i < 1000; i++) {
double intermediateResult = i;
}
}
它们最终都编译为空 是行
System.out.println(intermediateResult)代码>在执行测试时注释掉了?该代码看起来非常熟悉;)@保罗博丁顿是的,这是为了避免过度输出。@Zymus是的。。。也许我们也能得到一些反馈。那不是很好吗P@RuslanLópezCarro问题在于,如果您注释掉该行,则不会使用指定的值,因此可能会完全优化循环(我并不声称理解这些事情)。如果我将其设置为实际使用该值执行某些操作(例如,sum+=intermediateResult;
),则两个版本的时间都相似。然而,当我使用jdk1.8.0_25运行Andreas的精确代码时,我没有得到他的结果。对我来说,只有runCycles1
进入0
(即在循环外声明更快)。我已经试过好几次了,每次都很相似代码>在代码中。我希望这可以生成不同的字节码。
runCycles1() runCycles2()
Code: Code:
0: iconst_0 0: iconst_0 i = 0
1: istore_2 1: istore_0
2: goto 11 2: goto 11 goto 11
5: iload_2 5: iload_0 intermediateResult = (double)i
6: i2d 6: i2d
7: dstore_0 7: dstore_1
8: iinc 2, 1 8: iinc 0, 1 i++
11: iload_2 11: iload_0 if (i < 1000) goto 5
12: sipush 1000 12: sipush 1000
15: if_icmplt 5 15: if_icmplt 5
18: return 18: return return
for (int j = 0; j < 10; j++) {
long t1 = System.nanoTime();
for (int i = 0; i < 1000_000_000; i++)
runCycles1();
long t2 = System.nanoTime();
for (int i = 0; i < 1000_000_000; i++)
runCycles2();
long t3 = System.nanoTime();
System.out.printf("%d %d%n", t2 - t1, t3 - t2);
}
4250095 2020120
4067898 0
3904236 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0