JAVA JIT编译
分别使用lambda表达式以及普通for循环做测试
默认情况下启用JIT
package com.gao.demo;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
list.add((int) Math.random() * 100);
}
for (int i = 0; i <10 ; i++) {
System.out.println(i+" "+getTime(list));
}
}
public static long getTime(List<Integer> list) {
long start = System.currentTimeMillis();
list.forEach(i -> {
int tmp = i;
});
// for (int i:list) {
// int tmp=i;
// }
return System.currentTimeMillis()-start;
}
}
1、启用JIT以及Lambda
0 30
1 2
2 0
3 0
4 0
5 1
6 0
7 0
8 0
9 0
2、启用JIT以及普通for循环
0 6
1 1
2 0
3 0
4 0
5 0
6 1
7 0
8 0
9 0
使用lambda在首次加载的过程中耗费时间过久的原因:
显然,您遇到了lambda表达式的首次初始化开销。正如注释中已经提到的,lambda表达式的类是在运行时生成的,而不是从类路径加载的。然而,生成类并不是速度变慢的原因。毕竟,生成一个结构简单的类比从外部源加载相同的字节还要快。内部类也必须加载。但是,当应用程序以前没有使用lambda表达式时,甚至必须加载用于生成lambda类的框架(Oracle当前的实现在幕后使用ASM)。这是导致十几个内部使用的类(而不是lambda表达式本身)减速、加载和初始化的真正原因。
总结:
Lambda表达式在应用程序中首次使用时,需要额外加载ASM框架,因此需要更多的编译,加载的时间
Lambda表达式的底层实现并非匿名内部类的语法糖,而是其优化版
关闭JIT方法:
java -Xint your_main_class_file_name
java -Djava.compiler=NONE your_main_class_file_name
3、关闭JIT以及使用Lambda
0 33
1 5
2 7
3 5
4 6
5 5
6 5
7 6
8 5
9 5
4、关闭JIT以及使用普通for循环
0 10
1 13
2 13
3 12
4 11
5 11
6 12
7 11
8 15
9 10