对此可以做些什么?
我已经运行了一些测试,似乎 Scala Hashmap 比 Java HashMap 慢得多。请证明我错了!
对我来说,Hashmap 的全部意义在于从给定的键快速访问一个值。所以我发现自己在速度很重要时诉诸于使用 Java HashMap,这有点令人难过。我没有足够的经验可以肯定地说,但似乎您混合 Java 和 Scala 的次数越多,您可能面临的问题就越多。
test("that scala hashmap is slower than java") {
val javaMap = new util.HashMap[Int,Int](){
for (i <- 1 to 20)
put(i,i+1)
}
import collection.JavaConverters._
val scalaMap = javaMap.asScala.toMap
// check is a scala hashmap
assert(scalaMap.getClass.getSuperclass === classOf[scala.collection.immutable.HashMap[Int,Int]])
def slow = {
val start = System.nanoTime()
for (i <- 1 to 1000) {
for (i <- 1 to 20) {
scalaMap(i)
}
}
System.nanoTime() - start
}
def fast = {
val start = System.nanoTime()
for (i <- 1 to 1000) {
for (i <- 1 to 20) {
javaMap.get(i)
}
}
System.nanoTime() - start
}
val elapses: IndexedSeq[(Long, Long)] = {
(1 to 1000).map({_ => (slow,fast)})
}
var elapsedSlow = 0L
var elapsedFast = 0L
for ((eSlow,eFast) <- elapses) {
elapsedSlow += eSlow
elapsedFast += eFast
}
assert(elapsedSlow > elapsedFast)
val fraction : Double = elapsedFast.toDouble/elapsedSlow
println(s"slower by factor of: $fraction")
}
我错过了什么吗?
答案摘要
到目前为止,当将 Java 8 与 Scala 2.11 进行比较时,Java HashMap 的查找速度(对于少量键)似乎比 Scala 产品更快——LongMap 除外(如果您的键是 Ints/Longs)。
性能差异并不是很大,以至于在大多数用例中都应该很重要。希望 Scala 能够提高他们 Maps 的速度。同时,如果您需要性能(使用非整数键),请使用 Java。
整数键,n=20
Long(60)、Java(93)、Open(170)、MutableSc(243)、ImmutableSc(317)
case 对象键,n=20
Java(195), AnyRef(230)
最佳答案
首先:使用nanoTime 进行JVM 基准测试是极容易出错。使用微基准测试框架,例如 Thyme , Caliper或 JMH
第二:您正在将可变的 java 哈希映射与不可变的 scala 哈希映射进行比较。不可变集合可以非常快,但在某些情况下,它们永远不会像可变数据结构一样快。
这是可变 java 哈希映射与不可变 scala 哈希映射的适当微基准测试:https://gist.github.com/rklaehn/26c277b2b5666ec4b372
如您所见,scala 不可变映射比 java 可变映射要快一些。请注意,一旦您使用更大的 map ,情况就不会如此,因为不可变数据结构必须做一些妥协才能启用 structural sharing .我猜在这两种情况下,主要的性能问题是将整数装箱为整数。
更新:如果你真的想要一个以整数为键的可变散列 hap,scala 集合库中的正确选择是 scala.collection.mutable.LongMap .它使用 long as 键,并且比通用 Map 具有更好的性能,因为它不必对值进行装箱。查看要点的结果。
更新 2:如果您的 key 从 AnyRef 扩展(例如字符串),那么高性能可变映射的最佳选择是 scala.collection.mutable.AnyRefMap
关于scala - 为什么 Scala HashMap 很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28744990/