Java优化:内循环速度不一致?

前端之家收集整理的这篇文章主要介绍了Java优化:内循环速度不一致?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我的朋友和我都很难过.在这两个代码块中,为什么第一个内循环比第二个内循环快?这是某种JVM优化吗?

  1. public class Test {
  2. public static void main(String[] args) {
  3. int[] arr = new int[100000000];
  4. arr[99999999] = 1;
  5. long t1,t2,t3;
  6. for (int ndx = 0; ndx < 10; ndx++) {
  7. t1 = System.currentTimeMillis();
  8. for (int i = 0; i < arr.length; i++)
  9. if (0 < arr[i])
  10. System.out.print("");
  11. t2 = System.currentTimeMillis();
  12. for (int i = 0; i < arr.length; i++)
  13. if (arr[i] > 0)
  14. System.out.print("");
  15. t3 = System.currentTimeMillis();
  16. System.out.println(t2 - t1 +" "+(t3 - t2));
  17. }
  18. }
  19. }

结果如下:

  1. me@myhost ~ $java Test
  2. 57 80
  3. 154 211
  4. 150 209
  5. 149 209
  6. 150 209
  7. 150 209
  8. 151 209
  9. 150 210
  10. 150 210
  11. 149 209

颠覆了不平等的秩序:

  1. public class Test {
  2. public static void main(String[] args) {
  3. int[] arr = new int[100000000];
  4. arr[99999999] = 1;
  5. long t1,t3;
  6. for (int ndx = 0; ndx < 10; ndx++) {
  7. t1 = System.currentTimeMillis();
  8. for (int i = 0; i < arr.length; i++)
  9. if (arr[i] > 0)
  10. System.out.print("");
  11. t2 = System.currentTimeMillis();
  12. for (int i = 0; i < arr.length; i++)
  13. if (0 < arr[i])
  14. System.out.print("");
  15. t3 = System.currentTimeMillis();
  16. System.out.println((t2 - t1) +" "+(t3 - t2));
  17. }
  18. }
  19. }

结果如下:

  1. me@myhost ~ $java Test
  2. 56 80
  3. 155 210
  4. 150 209
  5. 149 209
  6. 151 210
  7. 149 209
  8. 150 209
  9. 149 208
  10. 149 209
  11. 149 208

精神错乱:一遍又一遍地做同样的事情并得到不同的结果.

最佳答案
简短回答:要避免此问题,请将您正在测试的代码放在单独的方法中.在你计时之前调用它11,000次来预热这个方法.这两个将允许JIT编译器将该方法与编译版本交换.使用-server运行,它只是更好地调整.使用System.nanoTime()计时.使用以下代码,您将获得一致的测量结果.

  1. public class AlphaTest
  2. {
  3. public static void processA(int[] arr)
  4. {
  5. for (int i = 0; i < arr.length; i++)
  6. if (arr[i] > 0)
  7. System.out.print("");
  8. }
  9. public static void processB(int[] arr)
  10. {
  11. for (int i = 0; i < arr.length; i++)
  12. if (0 < arr[i])
  13. System.out.print("");
  14. }
  15. public static void main(String[] args)
  16. {
  17. int[] smallArr = new int[10];
  18. for (int i = 0; i < smallArr.length; i++)
  19. {
  20. smallArr[i] = 1;
  21. }
  22. //warmup
  23. for (int i = 0; i < 11000; i++)
  24. {
  25. processA(smallArr);
  26. processB(smallArr);
  27. }
  28. int[] arr = new int[100000000];
  29. arr[99999999] = 1;
  30. long t1,t3;
  31. for (int ndx = 0; ndx < 10; ndx++)
  32. {
  33. t1 = System.nanoTime();
  34. processA(arr);
  35. t2 = System.nanoTime();
  36. processB(arr);
  37. t3 = System.nanoTime();
  38. System.out.println(((t2 - t1)/1000000L) + " " + ((t3 - t2)/1000000L));
  39. }
  40. }
  41. }

答案很长:
这绝对是Matt在评论中指出的“微基准标记”的问题.请参阅Azul Blog.为了支持这种观点,我得到以下结果取决于我如何运行程序:as -client as -server和JIT禁用每个设置只有2个结果行,其余类似.

  1. java -client -Xms1024m -Xmx1024m Test
  2. 272 262
  3. 263 252
  4. ...
  5. java -server -Xms1024m -Xmx1024m Test
  6. 513 173
  7. 483 201
  8. ...
  9. java -client -Djava.compiler=NONE -Xms1024m -Xmx1024m AlphaTest
  10. 2062 1929
  11. 2042 2034
  12. ...
  13. java -server -Djava.compiler=NONE -Xms1024m -Xmx1024m AlphaTest
  14. 1844 1864
  15. 1843 1931

猜你在找的Java相关文章