我尝试了以下代码:
public class Test {
public static void main(String[] args) {
int x = 9, y = 9, z = 0;
long startTime = System.currentTimeMillis();
// System.out.println("loop one start time = " + startTime);
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
z = x + y;
}
}
System.out.println("loop one use time = " + (System.currentTimeMillis() - startTime) + ",z = " + z);
startTime = System.currentTimeMillis();
// System.out.println("loop two start time = " + startTime);
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
z = sum(x, y);
}
}
System.out.println("loop two use time = " + (System.currentTimeMillis() - startTime) + ",z = " + z);
}
public static int sum(int x, int y) {
int t;
t = x + y;
return t;
}
}
控制台的输出是:
loop one use time = 216,z = 18
loop two use time = 70,z = 18.
似乎第二个循环花费的时间少于第一个循环! 我不明白为什么会这样。谢谢你的帮助。
更新: 我交换了两个循环,现在循环一个花费更少的时间!!
loop two use time = 219,z = 18
loop one use time = 69,z = 18
答案 0 :(得分:1)
Writing a correct micro-benchmark非常耗时且容易出错。我建议只使用已经可用的库进行微基准测试,例如Caliper,专为此而设计。
您的微基准测试存在很多缺陷,会导致不可预测的结果:
无论如何,这是使用Caliper完成的相应基准测试的代码:
@VmOptions("-server")
public class Test {
@Benchmark
public int timeSum1(long reps) {
int dummy = 0;
int x = 9, y = 9;
for (int j = 0; j < reps; j++) {
dummy = x + y;
}
return dummy;
}
@Benchmark
public int timeSum2(long reps) {
int dummy = 0;
int x = 9, y = 9;
for (int j = 0; j < reps; j++) {
dummy = sum(x, y);
}
return dummy;
}
public static int sum(int x, int y) {
int t;
t = x + y;
return t;
}
}
您可以在此处查看此基准测试的结果:
结果与预期一致:两种方法大致相同,因为它们可以由JIT编译器内联。使用-server运行这两种方法仍然需要大约相同的时间,但优化得更好。
答案 1 :(得分:0)
从阅读评论我得到了这个想法,尝试下面的代码
public class Test {
public static void main(String[] args) {
int x = 9, y = 9, z = 0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
z = x + y;
// z = sum(x, y);
}
}
long startTime = System.currentTimeMillis();
// System.out.println("loop one start time = " + startTime);
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
z = x + y;
}
}
System.out.println("loop one use time = "
+ (System.currentTimeMillis() - startTime) + ",z = " + z);
startTime = System.currentTimeMillis();
// System.out.println("loop two start time = " + startTime);
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
z = sum(x, y);
}
}
System.out.println("loop two use time = "
+ (System.currentTimeMillis() - startTime) + ",z = " + z);
}
public static int sum(int x, int y) {
int t;
t = x + y;
return t;
}
}
结果将显示两个循环具有相同的时间,导致JVM已经预热其内部功能并准备好在他的脚趾上服务。 :)
这也意味着你不能直接将某些代码使用的时间与它的算法直接相关,你需要控制相同的环境和参数来控制代码的时间消耗。