【问题标题】:Is a single array faster than 2 different arrays?单个阵列比 2 个不同的阵列快吗?
【发布时间】:2014-01-18 23:39:58
【问题描述】:

我想知道让一个数组存储某种数据是否比让多个数组存储相同的信息更有效。

int a1;
int a2;
int b1;
int b2;

int array1[] = {a1, b1, a2, b2}; // Is this faster than 2 arrays?

int array2A[] = {a1, a2};
int array2B[] = {b1, b2};

【问题讨论】:

  • 如果是这样,这只是一个令人难以置信的小收益,并且在清晰度方面付出了代价(从我从您的代码中可以看出)
  • 具体在什么情况下?一张String有多长?
  • 我正在使用两个不同的数组来存储顶点和颜色信息并考虑合并它们。
  • 数组不移动,所以不慢也不快。
  • 为什么不创建一个对象数组来保存您的信息。我认为第一个选项(一个数组)可能会因为缓存而快一点。

标签: java arrays performance


【解决方案1】:

这两个数组的缓存凝聚力可能会更差(因为它们位于内存的不同部分)。他们将使用少量更多的内存。不过,这些收益不太可能值得。专注于使您的程序尽可能好和架构良好,而不是担心这样的微小潜在收益,您将获得更好的结果。

【讨论】:

    【解决方案2】:

    实例化

    嗯,你可以争论这个。实例化 array1 需要 3 个字节码指令(bipushnewarrayastore),实例化 array2X 需要 3 个字节码指令每个数组bipush / iconst,@987654328 @,astore)。从理论上讲,实例化array1 可能会更快。

    访问

    这就是 VM 为获取 array1[2] 所做的操作:

    aload_1  ; array1
    iconst_2 ; index
    iaload   ; value
    

    猜猜得到array2B[0]的作用:

    aload_3  ; array2B on stack
    iconst_0 ; index
    iaload   ; value
    

    任何人都没有积分。

    内存

    数组的大小相等(array1array2A + array2B 一样大),至少是内容的大小。是的,有两个指针而不是一个,一些 GC 开销等等。不要想太多,你将无法衡量差异。

    缓存

    访问两个不同的对象显然会更慢。这个不用多说。一个对象绝对是可取的。

    变量访问和堆栈

    使用单个数组可能会提高整体性能,因为它有时可以保留在堆栈中。但是,JDK 编译器似乎避免了堆栈操作并回退到变量。

    结论

    不会有明显差异(尽管array1 通常会更快)。以上所有点都取决于 VM 实现。

    写好代码,不要过度优化。

    【讨论】:

      【解决方案3】:

      我认为在这两种情况下对元素的访问都是常数时间。但是,对于一个数组,您只需要一个指向数组头的指针,因此就内存而言,您可以说一个数组实现更有效。

      【讨论】:

        【解决方案4】:

        单个数组可能更高效:

        • 内存少了一点;
        • 缓存中只有一个对象。

        但是,我严重怀疑收益是否会超过缺点,我也怀疑性能提升(如果有的话) 会显着,或产生任何显着差异。

        如果您最终频繁地计算索引,您甚至可能失去性能。举以下例子:

        // With two arrays
        void sumBToA() {
            assert array2A.length == array2B.length;
            for (int i = 0; i < array2A.length; ++i) {
                array2A[i] = array2A[i] + array2B[i];
            }
        }
        
        // With one array
        void sumBToA() {
            for (int i = 0; i < array1.length; i += 2) {
                array1[i] = array1[i] + array1[i + 1];
            }
        }
        

        这是两次内存访问与两次内存访问索引计算。 同样,在大多数情况下,这可能不会产生任何重大影响。

        【讨论】:

          猜你喜欢
          • 2019-07-23
          • 2021-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-19
          • 2014-11-14
          • 1970-01-01
          相关资源
          最近更新 更多