【问题标题】:Performance implications of autoboxing on ArrayList of primitive wrappers对原始包装器的 ArrayList 进行自动装箱的性能影响
【发布时间】:2015-07-09 19:31:13
【问题描述】:

Java 不允许我们直接创建原语的ArrayList。但是我们可以创建一个原始包装类的ArrayList

但是当访问原始值时,编译器会自动进行包装和展开。这不是开销吗?我的问题是这对性能有何影响?

在这种情况下,int[] 的性能不会比 ArrayList<Integer> 更好吗?

有没有人测量过 int[]ArrayList<Inetger> 对于 Java5.0(首次引入时)和更高版本的 Java 的性能。如果您可以分享测试结果,这对遇到此问题的每个人都会有帮助。

【问题讨论】:

  • 数组和List 有不同的用法,在它们之间进行选择时通常不会降速。同样重要的是要知道每个ArrayList 的下面都是一个数组。
  • 原始数组更快(没有双倍的)但List(以及一般的任何集合)对对象更方便。所以选择是你的,但无论你做什么都不要使用旧数组作为公共接口。
  • @Obicere 是真的。我试图理解,如果我们为了一点灵活性而牺牲性能。这特定于我们必须在 int[] 和 ArrayList 之间做出选择时

标签: java collections performance-testing primitive autoboxing


【解决方案1】:

确实会增加一些开销。如果这对您来说是个问题,请考虑使用一些开箱即用的支持原语集合的库。例如TroveGuava 或 google 其他库

【讨论】:

    【解决方案2】:

    Eclipse CollectionsFastUtilTroveHPPC 等库中的原始集合将节省您的内存,并且通常比它们在 Java 中的盒装等效项执行得更好。每个库都将提供比int[] 更丰富的方法集。最好根据您的特定用例比较性能。

    我发现这篇题为“Performance Comparison of Primitive Lists in Java”的 Baeldung 文章比较了 FastUtil、Trove 和 Colt 原始列表。

    Eclipse Collections 开源库有几个原始集合,包括支持所有原始类型的 ListSetBagStackMap。已经有几篇文章使用性能基准来比较 JDK Collections 和 Eclipse Collections 原始集合的性能。

    NatTable 文章对int[]List<Integer> 进行了一些比较。

    注意:我是 Eclipse Collections 的提交者

    【讨论】:

      【解决方案3】:

      A question 被问及同一主题,并在 20M 元素 int[]ArrayList(我在计算机上重新运行,来自 @Wsl_F 问题)的以下基准测试结果:

      public static void main(String[] args) {
          int n = 20_000_000;
          System.out.println("Warming up...");
          list(n);
          array(n);
          long t0 = System.nanoTime();
          int v = list(n);
          t0 = System.nanoTime() - t0;
          System.out.printf("list %.1f ms (%d)\n", (t0 / 1000000.0), v);
      
          t0 = System.nanoTime();
          v = array(n);
          t0 = System.nanoTime() - t0;
          System.out.printf("array %.1f ms (%d)\n", (t0 / 1000000.0), v);
      }
      
      private static int list(int n) {
          ArrayList<Integer> list = new ArrayList<>(n);
          for (int i = 0; i < n; i++)
              list.add(i);
          return list.get(n/2);
      }
      
      private static int array(int n) {
          int[] list = new int[n];
          for (int i = 0; i < n; i++)
              list[i] = i;
          return list[n/2];
      }
      

      给我(Ubuntu 16.04 x64 和 Intel Core i7 上的 Eclipse):

      list 1839,9 ms (10000000)
      array 515,9 ms (10000000)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-12
        • 1970-01-01
        • 2010-09-19
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多