Java for loop performance question(Java for 循环性能问题)
问题描述
考虑这个例子:
public static void main(final String[] args) {
final List<String> myList = Arrays.asList("A", "B", "C", "D");
final long start = System.currentTimeMillis();
for (int i = 1000000; i > myList.size(); i--) {
System.out.println("Hello");
}
final long stop = System.currentTimeMillis();
System.out.println("Finish: " + (stop - start));
}
对比
public static void main(final String[] args) {
final List<String> myList = Arrays.asList("A", "B", "C", "D");
final long start = System.currentTimeMillis();
final int size = myList.size();
for (int i = 1000000; i > size; i--) {
System.out.println("Hello");
}
final long stop = System.currentTimeMillis();
System.out.println("Finish: " + (stop - start));
}
这会有什么不同吗?在我的机器上,第二个似乎执行得更快,但我不知道它是否真的准确.编译器会优化这段代码吗?如果循环条件是不可变对象(例如字符串数组),我可以认为他会这样做.
Will this make any diffrence ? On my machine the second one seems to perform faster but i don't know if it is really accurate. Will the compiler optimze this code ? I could think that he would if the loop condition is an immutable object (e.g. String array).
推荐答案
如果你想测试这样的东西,你真的必须优化你的微基准来衡量你关心的东西.
If you want to test something like this, you really must optimize your microbenchmark to measure what you care about.
首先,使循环廉价但不可能跳过.计算总和通常可以解决问题.
First, make the loop inexpensive but impossible to skip. Computing a sum usually does the trick.
其次,比较两个时序.
这里有一些代码可以做到这两点:
Here's some code that does both:
import java.util.*;
public class Test {
public static long run1() {
final List<String> myList = Arrays.asList("A", "B", "C", "D");
final long start = System.nanoTime();
int sum = 0;
for (int i = 1000000000; i > myList.size(); i--) sum += i;
final long stop = System.nanoTime();
System.out.println("Finish: " + (stop - start)*1e-9 + " ns/op; sum = " + sum);
return stop-start;
}
public static long run2() {
final List<String> myList = Arrays.asList("A", "B", "C", "D");
final long start = System.nanoTime();
int sum = 0;
int limit = myList.size();
for (int i = 1000000000; i > limit; i--) sum += i;
final long stop = System.nanoTime();
System.out.println("Finish: " + (stop - start)*1e-9 + " ns/op; sum = " + sum);
return stop-start;
}
public static void main(String[] args) {
for (int i=0 ; i<5 ; i++) {
long t1 = run1();
long t2 = run2();
System.out.println(" Speedup = " + (t1-t2)*1e-9 + " ns/op
");
}
}
}
如果我们运行它,在我的系统上我们会得到:
And if we run it, on my system we get:
Finish: 0.481741256 ns/op; sum = -243309322
Finish: 0.40228402 ns/op; sum = -243309322
Speedup = 0.079457236 ns/op
Finish: 0.450627151 ns/op; sum = -243309322
Finish: 0.43534661700000005 ns/op; sum = -243309322
Speedup = 0.015280534 ns/op
Finish: 0.47738474700000005 ns/op; sum = -243309322
Finish: 0.403698331 ns/op; sum = -243309322
Speedup = 0.073686416 ns/op
Finish: 0.47729349600000004 ns/op; sum = -243309322
Finish: 0.405540508 ns/op; sum = -243309322
Speedup = 0.071752988 ns/op
Finish: 0.478979617 ns/op; sum = -243309322
Finish: 0.36067492700000003 ns/op; sum = -243309322
Speedup = 0.11830469 ns/op
这意味着方法调用的开销大约为 0.1 ns.如果您的循环执行的时间不超过 1-2 ns,那么您应该关心这一点.否则,不要.
which means that the overhead of the method call is approximately 0.1 ns. If your loop does things that take no more than 1-2 ns, then you should care about this. Otherwise, don't.
这篇关于Java for 循环性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java for 循环性能问题


基础教程推荐
- Java:带有char数组的println给出乱码 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 降序排序:Java Map 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01