加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 19:17:52 所属栏目:Java 来源:网络整理
导读:我的朋友和我都很难过.在这两个代码块中,为什么第一个内循环比第二个内循环快?这是某种JVM优化吗? public class Test { public static void main(String[] args) { int[] arr = new int[100000000]; arr[99999999] = 1; long t1,t2,t3; for (int ndx = 0;

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

public class Test {
   public static void main(String[] args) {
      int[] arr = new int[100000000];
      arr[99999999] = 1;
      long t1,t2,t3;
      for (int ndx = 0; ndx < 10; ndx++) {
         t1 = System.currentTimeMillis();
         for (int i = 0; i < arr.length; i++)
            if (0 < arr[i])
               System.out.print("");

         t2 = System.currentTimeMillis();
         for (int i = 0; i < arr.length; i++)
            if (arr[i] > 0)
               System.out.print("");

         t3 = System.currentTimeMillis();
         System.out.println(t2 - t1 +" "+(t3 - t2));
      }
   }
}

结果如下:

me@myhost ~ $java Test
57 80
154 211
150 209
149 209
150 209
150 209
151 209
150 210
150 210
149 209

颠覆了不平等的秩序:

public class Test {
   public static void main(String[] args) {
      int[] arr = new int[100000000];
      arr[99999999] = 1;
      long t1,t3;
      for (int ndx = 0; ndx < 10; ndx++) {
         t1 = System.currentTimeMillis();
         for (int i = 0; i < arr.length; i++)
            if (arr[i] > 0)
               System.out.print("");

         t2 = System.currentTimeMillis();
         for (int i = 0; i < arr.length; i++)
            if (0 < arr[i])
               System.out.print("");

         t3 = System.currentTimeMillis();
         System.out.println((t2 - t1) +" "+(t3 - t2));
      }
   }
}

结果如下:

me@myhost ~ $java Test
56 80
155 210
150 209
149 209
151 210
149 209
150 209
149 208
149 209
149 208

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

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

public class AlphaTest
{
public static void processA(int[] arr)
{
    for (int i = 0; i < arr.length; i++)
        if (arr[i] > 0)
            System.out.print("");
}

public static void processB(int[] arr)
{
    for (int i = 0; i < arr.length; i++)
        if (0 < arr[i])
            System.out.print("");
}

public static void main(String[] args)
{
    int[] smallArr = new int[10];
    for (int i = 0; i < smallArr.length; i++)
    {
        smallArr[i] = 1;
    }
    //warmup
    for (int i = 0; i < 11000; i++)
    {
        processA(smallArr);
        processB(smallArr);
    }

    int[] arr = new int[100000000];
    arr[99999999] = 1;
    long t1,t3;
    for (int ndx = 0; ndx < 10; ndx++)
    {
        t1 = System.nanoTime();
        processA(arr);

        t2 = System.nanoTime();
        processB(arr);

        t3 = System.nanoTime();
        System.out.println(((t2 - t1)/1000000L) + " " + ((t3 - t2)/1000000L));
    }
}
}

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

java -client -Xms1024m -Xmx1024m Test
272 262
263 252
...
java -server -Xms1024m -Xmx1024m Test
513 173
483 201
...
java -client -Djava.compiler=NONE -Xms1024m -Xmx1024m AlphaTest
2062 1929
2042 2034
...
java -server -Djava.compiler=NONE -Xms1024m -Xmx1024m AlphaTest
1844 1864
1843 1931

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读