我有需要迭代的列表。我使用的是Java 8中的新foreach。我发现它比旧的不那么优雅的方法慢得多。我已经阅读了this堆栈讨论,其中更多地关注最佳实践而不是真实世界的实现。我理解,对于lambda来说,还有额外的开销来源于方法传递,但我仍然不理解第一个和第三个案例之间的差异,并且我认为我可能错误地使用它。还没有为lambda实现优化,还是有更好的方法可以使用它们来获得更高的性能?下面是一个示例性示例,而不是我的实际代码。
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Memes> memesList =
Arrays.asList(
new OldMemes(),
new TrendingMemes()
);
//----------------------------Benchmark
long start, end;
start = System.nanoTime();
System.out.format("for each started @%d\n", start);
//Old way.
for(Memes memes : memesList){
memes.showMeme();
}
//-----------------------------Benchmark
end = System.nanoTime();
System.out.println((end - start));
start = System.nanoTime();
System.out.format("for started @%d\n", start);
//Other way
for(Iterator<Memes> i = memesList.iterator(); i.hasNext(); ) {
i.next().showMeme();
}
//-----------------------------Benchmark
end = System.nanoTime();
System.out.println((end - start));
start = System.nanoTime();
System.out.format("for each lambda started @%d\n", start);
//New way.
memesList.forEach((memes) -> memes.showMeme());
//-----------------------------Benchmark
end = System.nanoTime();
System.out.println((end - start));
System.out.format("end @%d\n", end);
}
interface Memes {
public void showMeme();
}
static class OldMemes implements Memes {
@Override
public void showMeme() {
System.out.println("Id appetere senserit his, nonumes consulatu vel id.");
}
}
static class TrendingMemes implements Memes {
@Override
public void showMeme() {
System.out.println("Id appetere senserit his, nonumes consulatu vel id.");
}
}
}
答案 0 :(得分:9)
您的基准测试非常错误。您只为这两种技术应用一个循环(仅两个元素)。你应该重复这个至少一万亿次。同时增加数组的大小,使用至少50个元素。接下来,在基准测试时不要打印到stdout。这需要花费太多时间并且是同步操作,并且会产生错误的结果。
阅读此主题以获得更好的结果:How do I write a correct micro-benchmark in Java?