jvm学习三--jit的理解

         下面一段代码:

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的理解很浅。。。    只是知道有这么个东西,他的作用是什么,但是对我们编码有什么大的影响,还不清楚。。。 特别希望有大神能解惑。。  希望大神拍砖

 

猜你喜欢

转载自709002341.iteye.com/blog/2274816