? ? ? ? ?下面一段代码:
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