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

java – 大型小对象的慢速初始化

发布时间:2020-12-15 04:31:07 所属栏目:Java 来源:网络整理
导读:我今天偶然发现了这个案子,我想知道这个巨大差异背后的原因是什么. 第一个版本初始化一个5k x 5k的raw int数组: public void initializeRaw() { int size = 5000; int[][] a = new int[size][size]; for (int i = 0; i size; i++) for (int j = 0; j size;
我今天偶然发现了这个案子,我想知道这个巨大差异背后的原因是什么.

第一个版本初始化一个5k x 5k的raw int数组:

public void initializeRaw() {
  int size = 5000;
  int[][] a = new int[size][size];
  for (int i = 0; i < size; i++)
    for (int j = 0; j < size; j++)
      a[i][j] = -1;
}

我的机器大约需要300毫秒.
另一方面,使用简单的2-int结构初始化相同的数组:

public class Struct { public int x; public int y; }

public void initializeStruct() {
  int size = 5000;
  Struct[][] a = new Struct[size][size];
  for (int i = 0; i < size; i++)
    for (int j = 0; j < size; j++)
      a[i][j] = new Struct();
}

花费超过15000ms.

我希望它有点慢,毕竟有更多的内存要分配(如果我没有弄错的话,10个字节而不是4个字节),但我不明白为什么它需要花费50倍的时间.

有人能解释一下吗?也许只有更好的方法来进行Java中的这种初始化?

编辑:对于一些比较 – 使用Integer而不是int / Struct的相同代码工作700ms – 只慢两倍.

解决方法

当您创建5000个int的数组时,您将一次性分配所有这些整数所需的所有空间,作为单个连续元素块.为每个数组元素分配一个int时,您没有分配任何内容.与5000个Struct实例的数组形成对比.您遍历该数组,并为这5000个元素中的每一个元素分配一个Struct实例.分配对象比简单地将int值写入变量需要花费更长的时间.

你有二维数组的事实在这里没有太大的比较差异,因为它只是意味着你在两种情况下都分配5000个数组对象.

如果要对一组Integer对象进行计时,然后将每个元素设置为-1,那么每次都不会分配单独的Integer对象.相反,您正在使用自动装箱,这意味着编译器隐式调用Integer.valueOf(-1),并且该方法每次都从缓存中返回相同的对象.

更新:回过头来解决您的问题,如果我理解正确,您需要将5000×5000 Structs保留在2D数组中,并且您对创建此数组比使用原语需要更长时间感到失望.为了提高性能,您可以创建两个基元数组,一个用于Struct的每个字段,但这会降低代码清晰度.

你也可以创建一个long数组(因为每个long的长度是int的两倍)并使用&和>>操作符获得原始的整数.同样,这会降低代码清晰度,但是你只有一个数组.

但是,您似乎专注于代码的单个部分,即数组的创建.您可能会发现,对每个元素执行的处理会使创建数组所花费的时间过多.分析整个应用程序,看看阵列的创建是否重要.

(编辑:李大同)

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

    推荐文章
      热点阅读