对于 Scala 2.13,更新具有数百万更新的 LongMap、HashMap 或 TrieMap 的最快方法是什么?

For Scala 2.13, what is the fastest method for updating a LongMap, HashMap, or TrieMap with millions of updates?

目标

我有一个包含数百万条目的可变 Map[Long, Long]。我需要使用数百万个更新进行多次更新迭代。我想尽快完成。

背景

目前,最快的方法是使用单线程mutable.LongMap[Long]。此类型针对 Long 类型作为键进行了优化。

其他地图类型似乎更慢 -- 但我可能没有正确实施它们,因为我试图并行 and/or 并发更新但没有成功。在 Scala 中并行更新地图可能实际上并没有发生或不可能。

从最快到最慢的顺序:

  1. LongMap[Long](自上而下)
  2. TrieMap[长, 长]
  3. ParTrieMap[长, 长]
  4. HashMap[长, 长]
  5. ParHashMap[长, 长]
  6. ParMap[长, 长]

如果更快的方法是不可变的,那没关系,但我认为情况不会如此。可变映射可能最适合此用例。

生成测试数据和测试时间的代码

import java.util.Calendar
import scala.collection.mutable

object DictSpeedTest2 {

  //helper constants
  val million: Long = 1000000
  val billion: Long = million * 1000

  //config
  val garbageCollectionWait = 3
  val numEntries: Long = million * 10 //may need to increase JVM memory with something like: -Xmx32g
  val maxValue: Long = billion * million // max Long = 9223372036854775807L
                                         // this is       1000000000000000L

  def main(args: Array[String]): Unit = {
    //generate random data; initial entries in a; updates in b
    val a = genData(numEntries, maxValue, seed = 1000)
    val b = genData(numEntries, maxValue, seed = 9999)

    //initialization
    val dict = new mutable.LongMap[Long]()
    a.foreach(x => dict += (x._1 -> x._2))

    //run and time test
    println("start test: " + Calendar.getInstance().getTime)
    val start = System.currentTimeMillis
    b.foreach(x => dict += (x._1 -> x._2)) //updates
    val end = System.currentTimeMillis

    //print runtime
    val durationInSeconds = (end - start).toFloat / 1000 + "s"
    println("end test:  " + Calendar.getInstance().getTime + " -- " + durationInSeconds)
  }

  def genData(n: Long, max: Long, seed: Long): Array[(Long, Long)] = {
    val r = scala.util.Random
    r.setSeed(seed) //deterministic generation of arrays
    val a = new Array[(Long, Long)](n.toInt)
    a.map(_ => (r.nextInt(), r.nextInt()) )
  }
}

当前时间

带有上述代码的 LongMap[Long] 在我的 2018 MacBook Pro 上按以下时间完成:

如果您不限于仅使用 Scala/Java 地图而不是为了获得卓越的性能,您可以查看具有专门用于 Long/Long key/value 对的地图的第 3 方库。

Here 对此类具有 Int/Int 对基准测试结果的库的概述并不算过时。