? ? ? ? ?下面一段代码:
public static void main(String[] args) {
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
int j = 0;
for(int i = 0; i < 100000000; i++){
j += i;
}
long end = System.currentTimeMillis();
System.out.println("程序执行:"+(end - start));
}
? ? ? ?不加任何参数执行的结果是:程序执行:6 ??
? ? ? ?使用参数-Xint(忽略jit编译器)执行的结果是:程序执行:1206
? ? ? ?可以看到。。。 ? ?这效率快了两个数量级还多。。。
? ? ? ? java有非常优秀的jit编译器,可以对频繁执行的“热代码”进行即时编译。
? ? ? ? 很多人都知道jvm执行代码的过程是:java字节码(class文件)-》jvm解释器解释成机器语言-》执行结果。 ? 这也是java为什么跨平台的原因-----其实跨平台的不是java,而是jvm。因为不同的平台有不同的jvm,可以将class文件解释成相应平台的机器语言。
? ? ? ? 而jit是将“热代码”直接编译成机器语言,不经过中间的解释过程,而且编译后的机器语言直接缓存起来,就是说“热代码”在经过一次编译以后,就可以直接以机器语言的形式执行了,不再有中间环节。所以jit可以在很大程度上提升频繁执行的代码的性能。
? ? ? ? 如果上面的代码用参数-Xcomp执行(优先jit编译器),结果是:程序执行:1。。 ?很强大,应该可以跟c的速度媲美了。。。 但是,用这个参数的时候中间明显有个停顿过程(猜想是jit编译器将代码编译成机器语言),所以执行之后会有个明显的停顿。如果是只执行一次或少次的代码,jit的效率并没有jvm高。
? ? ? ? 下面是我以前写的一个插入排序的代码,分别用两个参数执行:
package sort;
import java.util.Random;
public class InsertSort {
private static int MAX = 1000000;
/**
* @Title: main
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param args 设定文件
* @return void 返回类型
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] is = new int[MAX];
int[] shell = new int[MAX / 2];
for (int i = 0; i < shell.length; i++) {
if (i == 0) {
shell[i] = MAX / 2;
} else {
shell[i] = shell[i - 1] / 2;
}
}
shell[shell.length - 1] = 1;
for (int i = 0; i < MAX; i++) {
is[i] = new Random().nextInt(MAX);
}
long start = System.currentTimeMillis();
shellSort(is, shell);
long end = System.currentTimeMillis();
System.out.println("程序执行了" + (end - start) + "毫秒");
}
/**
* @Title: directSort
* @Description: TODO(直接排序)
* @param 设定文件
* @return void 返回类型
*/
public static void directSort(int[] is) {
/**
* 第0个是已经排好序的,所以从第一个开始插入
*/
for (int i = 1; i < is.length; i++) {
/**
* 每一个元素与前边已经排好的元素做比较
*/
int k;
int temp = is[i];
for (k = i - 1; k >= 0 && is[k] > temp; k--) {
is[k + 1] = is[k];
}
is[k + 1] = temp;
}
}
/**
* @Title: directSort
* @Description: TODO(直接排序(递归思想))
* @param i
* 前i个元素已经排序
* @return void 返回类型
*/
public static void directSort2(int[] is, int i) {
if (i == is.length) {
return;
}
for (int k = 0; k <= i; k++) {
if (is[k] > is[i]) {
reverse(is, i, k);
}
}
directSort2(is, i + 1);
}
/**
* @Title: binarySort
* @Description: TODO(二分插入排序)
* @param @param is 设定文件
* @return void 返回类型
*/
private static void binarySort(int[] is) {
/**
* 第0个是已经排好序的,所以从第一个开始插入
*/
for (int i = 1; i < is.length; i++) {
/**
* 每一个元素与前边已经排好的元素做比较
*/
int temp = is[i];
int left = 0;
int right = i - 1;
int mid = (left + right) / 2;
while (left <= right) {
if (temp > is[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
mid = (left + right) / 2;
}
reverse(is, i, left);
}
}
/**
* @Title: shellSort
* @Description: TODO(希尔排序)
* @param @param is
* @return void 返回类型
*/
private static void shellSort(int[] is, int[] shell) {
for (int i = 0; i < shell.length; i++) {
int d = shell[i];
for (int j = 0; j < d; j++) {
for (int k = j + d; k < is.length; k = k + d) {
int temp = is[k];
int m;
for (m = k - d; m >= 0 && is[m] > temp; m = m - d) {
is[m + d] = is[m];
}
is[m + d] = temp;
}
}
}
}
/**
*
* @Title: reverse
* @Description: TODO(把第j位赋值到第i位,第i位以后依次后移)
* @param @param is
* @param @param i
* @param @param j 设定文件
* @return void 返回类型
*/
private static void reverse(int[] is, int i, int j) {
if (i == j) {
return;
}
int temp = is[i];
while (i > j) {
is[i] = is[--i];
}
is[j] = temp;
}
}
?用-Xint执行结果:程序执行了2321毫秒
用-Xcomp执行的结果:程序执行了211毫秒
默认执行结果:程序执行了236毫秒
? 不过-Xcomp参数明显有个停顿,没有默认执行的效率高。
? ? ?所以一般情况下,还是让他默认吧,除非你是大神,并且需要通过调节参数来提高算法效率。
? ? ? ?jit对代码效率的提升还表现在方法内联上:默认情况下jit会对字节数小于35的方法进行内联操作。这对我们的启示就是方法尽可能小吧(最近看源码发现java源码是一个赛一个的小,可能跟这个有关。。。)
? ? ? 个人对jit的理解很浅。。。 ? ?只是知道有这么个东西,他的作用是什么,但是对我们编码有什么大的影响,还不清楚。。。 特别希望有大神能解惑。。 ?希望大神拍砖
?
原文:http://709002341.iteye.com/blog/2274816