【问题标题】:Efficent insertion into a collection of long values高效插入长值集合
【发布时间】:2011-07-05 09:40:18
【问题描述】:

我正在为一段代码进行指标收集,并希望存储一组时间差异(类型原始long)以供以后分析

此集合的插入操作应尽可能高效,以尽量减少对结果的开销。

我首先测试了一个ConcurrentLinkedQueue<Long> 集合。这给出了最差的性能(可能是由于装箱/拆箱)

我目前已决定使用 同步 gnu.trove.TLongArrayList,对于 500 万长的数据集,它的速度几乎快 7 倍。

我们非常感谢任何对可能成为此用例基准测试的优秀候选者的其他馆藏库的建议。我查看了 guava API,但似乎找不到任何东西

【问题讨论】:

  • 为什么需要线程安全的数据收集?是否有必要将所有值保存在一个集合中?在插入期间,您是否还尝试从集合中读取/删除?
  • @Salman 线程安全是一项要求,因为正在测试的代码是多线程的。不必将所有值保存在一个集合中。请随时提出替代数据结构的建议。不需要移除。读取发生在结果分析期间的测试后,因此它们的效率无关紧要。
  • 你也可以发布一些数字吗?例如,当您说它的性能*最差时,需要多长时间?小时、分钟、秒?

标签: java collections guava


【解决方案1】:

为了提高性能,您可以做的就是减少数据类型的大小。如果您可以将其减少到int,那将有所帮助。 (通常两次调用 nanoTime() 之间的差异小于 20 亿)

您可以为集合设置一个好的起始大小。尤其是如果你知道你可能有多少。

如果您知道要记录的最大值数,您可以使用int[],如果未达到最大值,则可以使用counter。这比使用对象更快。

【讨论】:

    【解决方案2】:

    Trove 的新版本正在筹备中(最新版本是 3.0.0-RC2)。 This page 表示 Trove 3 比 Trove 2 快 10% 到 20%。

    不幸的是:

    • Trove 3 具有 API 兼容性重大更改。
    • 在线 javadocs 尚不可用。
    • 您还不能从 Maven Central 获取它。 (你甚至无法获得 Trove 2.1.0 ...啧啧啧。)

    【讨论】:

      【解决方案3】:

      你应该试试fastutil。取决于场景,fastutil 可能比 trove4j 更快

      【讨论】:

        【解决方案4】:

        我不确定您的情况是否允许这样做,但您是否考虑将数据保存在每个线程的单独、不同步的数据结构中?类似于包含 TLongArrayList 的 ThreadLocal。这将消除同步开销。

        【讨论】:

        • 取决于有多少竞争,这可能是一个非常大的胜利。
        【解决方案5】:

        如果您提前知道集合的大小,则可以使用单个未同步的 long[] 数组和 AtomicInteger 计数器来获取下一个插入位置。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-01-26
          • 1970-01-01
          • 1970-01-01
          • 2015-04-12
          • 2020-04-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多