【问题标题】:Kotlin's Array vs ArrayList vs List for storing large amounts of dataKotlin Array vs ArrayList vs List 用于存储大量数据
【发布时间】:2020-12-16 10:12:15
【问题描述】:

我正在 Kotlin 中构建一个深度神经网络(我知道 Python 会更好,但我必须在 Kotlin 中这样做)。

为了训练网络,我需要来自MNIST database 的大量数据,这意味着我需要从一个 IDX 格式的文件中读取大约 60,000 张图像并将它们存储起来以供同时使用。

每个图像由 784 个字节组成。所以总大小是: 784*60,000 = 47,040,000 = ~47 MB​​ 的训练数据。 这不算多,因为我在 8GB RAM 环境中运行 JVM。

读取图像后,我需要将其转换为KMatrix,这是一种用于矩阵数学运算的自定义数据结构。在KMatrix 的引擎盖下有一个Array<Array<Double>>

我需要一个结构来一次存储所有图像,所以我目前使用的是List<KMatrix>,它基本上转换为List<Array<Array<Double>>>

问题在于,在构建 List<KMatrix> 时,垃圾收集器会耗尽内存,从而启动 OutOfMemoryException: GC overhead limit exceeded

我想知道问题是我正在使用 哪些 数据结构(即我应该使用 ArrayList 而不是 Array 吗?)或者可能是 如何 我正在构建整件事(即我需要做一些优化工作)。

如果需要,我会尽快提供代码。

感谢您的帮助。

【问题讨论】:

  • 通过将Array<Array<Double>> 替换为Array<DoubleArray>,您将大大节省内存和性能。更进一步,您可以使用一维DoubleArray 并使用[row * width + column] 获取您的元素。更进一步,您可以考虑使用DoubleBuffer 而不是DoubleArray
  • 我认为这正是我想要的。非常感谢!
  • 不客气。关于 DoubleBuffer,您需要使用 ByteBuffer.allocateDirect(8 * size).asDoubleBuffer() 而不是 DoubleBuffer.allocate(size)。直接缓冲区表现更好。
  • 转换Array<Double>DoubleArray 几乎总是值得的,因为后者将值存储为原语,避免了前者需要的所有装箱的Double 对象。 (对于其他原始数组类型也是如此。)——然而,将这些数组转换成一个带有手动索引的单个数组会节省很多,而且不太可能证明额外的复杂性是合理的。
  • @gidds 是的,你可能是对的,但由于在深度学习中节省每一毫秒都是值得的,所以无论如何我都在尝试实现它。此外,在我的具体情况下,使用 1D DoubleArray 有一些非常简单的操作 - 例如将任何给定的 (Double) -> (Double) lambda 应用于 KMatrix 的每个元素。这不是一个巨大的进步,但仍然是双赢。

标签: kotlin data-structures memory-leaks garbage-collection out-of-memory


【解决方案1】:

使用总结的解决方案进行自我回答(感谢@Tenfour04 和@gidds 的回答)

正如@Tenfour04 所说,对于KMatrix,您基本上有三个替代Array<Array<Double>>

  1. Array<DoubleArray> 保持与原始逻辑相同的逻辑,但节省了大量内存并提高了性能;
  2. 一维DoubleArray,它节省了一些额外的内存和性能,但数组的索引映射给出了增加的复杂性(矩阵的[i;j]元素由[i * w + j] 数组的元素),正如@gidds 指出的那样,这可能不值得;
  3. 使用ByteBuffer.allocateDirect(8 * size).asDoubleBuffer() 创建的一维DoubleBuffer,进一步提高了性能,但只有getput 方法,所以如果您需要简单直接的集合操作,它是无用的。

结论 我选择选项 2,因为在我的情况下,我正在执行非常密集的操作,但在通常情况下,选项 1 可能是最好的,因为它在复杂性和性能方面取得了平衡。 如果您需要一个最高性能的结构并且读取/放置方法就足够了,我会说选项 3 就是您正在寻找的。​​p>

希望这对某人有所帮助

【讨论】:

    猜你喜欢
    • 2021-12-19
    • 2012-08-07
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2018-08-23
    • 1970-01-01
    相关资源
    最近更新 更多