Java (Android) 中的大型二维数组存储
Large 2D Array Storage in Java (Android)
我正在 Java 中创建一个矩阵,其中:
- 最坏情况下最多可以有 10,000 x 10,000 个元素
- 可能会不时更改大小(假设以天为单位)
- 存储 0-5 范围内的整数(大概是
byte
)
- 具有通过引用一对
Long
ID(系统确定)访问的元素
- 是对称的(所以如果需要的话,可以用 space 的一半来完成,尽管它会使行求和之类的事情变得更难(如果数组是无序的,则不可能))
- 不一定需要排序(除非分成三角形,如上所述)
- 需要在应用程序关闭后保持不变(当前正在写入文件)
我当前的实现是使用 HashMap<Pair<Long,Long>,Integer>
,它在我的小测试矩阵 (10x10) 上运行良好,但根据 this article,当扩展到 10,000 时可能会遇到难以管理的内存使用x 10,000 个元素。
我是 Java 和 Android 的新手,我想知道:这种事情的最佳实践是什么?
我正在考虑切换回沼泽标准二维数组 byte[][]
,并为我的 Long
ID 使用 HashMap
查找 table。我会在矩阵访问方面受到显着的性能影响吗?另外,我认为没有任何一种方法就无法修改数组大小:
- 为假设的最坏情况预分配(这甚至可能不是最坏的情况,并且会占用不必要的内存量)
- 如果需要更改大小,则将数组复制到新数组中(暂时使我的内存使用量增加一倍)
以为我会为后代回答这个问题。我采纳了 Fildor 的建议,即使用带有两个查找列的 SQL 数据库来表示我的 "matrix" 的行索引和列索引。该值存储在第三列中。
这种方法的主要好处是不需要将整个矩阵加载到 RAM 中来读取或更新元素,还有一个额外的好处是可以访问求和函数(以及 SQL 数据库)。由于内置 SQL 功能,在 Android 上这是一个特别简单的方法。
一个性能缺点是矩阵的初始化非常慢。但是,我采用的方法是假设如果在数据库中找不到某个条目,则它采用默认值。这消除了填充整个矩阵的需要(并且对稀疏矩阵特别有用),但缺点是在尝试访问无效索引时不会抛出错误。建议将此方法与一对列出有效行和列的列表结合使用,并在尝试访问数据库之前引用这些列表。如果您尝试使用内置的 SQL 功能对行求和,如果您的默认值为非零,这也将无法正常工作,尽管这可以通过返回 [=] 中找到的条目数来解决18=] 求和,并将 "missing" 元素乘以默认值。
我正在 Java 中创建一个矩阵,其中:
- 最坏情况下最多可以有 10,000 x 10,000 个元素
- 可能会不时更改大小(假设以天为单位)
- 存储 0-5 范围内的整数(大概是
byte
) - 具有通过引用一对
Long
ID(系统确定)访问的元素 - 是对称的(所以如果需要的话,可以用 space 的一半来完成,尽管它会使行求和之类的事情变得更难(如果数组是无序的,则不可能))
- 不一定需要排序(除非分成三角形,如上所述)
- 需要在应用程序关闭后保持不变(当前正在写入文件)
我当前的实现是使用 HashMap<Pair<Long,Long>,Integer>
,它在我的小测试矩阵 (10x10) 上运行良好,但根据 this article,当扩展到 10,000 时可能会遇到难以管理的内存使用x 10,000 个元素。
我是 Java 和 Android 的新手,我想知道:这种事情的最佳实践是什么?
我正在考虑切换回沼泽标准二维数组 byte[][]
,并为我的 Long
ID 使用 HashMap
查找 table。我会在矩阵访问方面受到显着的性能影响吗?另外,我认为没有任何一种方法就无法修改数组大小:
- 为假设的最坏情况预分配(这甚至可能不是最坏的情况,并且会占用不必要的内存量)
- 如果需要更改大小,则将数组复制到新数组中(暂时使我的内存使用量增加一倍)
以为我会为后代回答这个问题。我采纳了 Fildor 的建议,即使用带有两个查找列的 SQL 数据库来表示我的 "matrix" 的行索引和列索引。该值存储在第三列中。
这种方法的主要好处是不需要将整个矩阵加载到 RAM 中来读取或更新元素,还有一个额外的好处是可以访问求和函数(以及 SQL 数据库)。由于内置 SQL 功能,在 Android 上这是一个特别简单的方法。
一个性能缺点是矩阵的初始化非常慢。但是,我采用的方法是假设如果在数据库中找不到某个条目,则它采用默认值。这消除了填充整个矩阵的需要(并且对稀疏矩阵特别有用),但缺点是在尝试访问无效索引时不会抛出错误。建议将此方法与一对列出有效行和列的列表结合使用,并在尝试访问数据库之前引用这些列表。如果您尝试使用内置的 SQL 功能对行求和,如果您的默认值为非零,这也将无法正常工作,尽管这可以通过返回 [=] 中找到的条目数来解决18=] 求和,并将 "missing" 元素乘以默认值。