Eya*_*oth 0 collections performance scala
我遇到了一个关于将可变集合转换为不可变集合的奇怪行为,这可能会显着影响性能.
我们来看看下面的代码:
val map: Map[String, Set[Int]] = createMap()
while (true) {
map.get("existing-key")
}
Run Code Online (Sandbox Code Playgroud)
它只创建一次映射,然后重复访问其中一个enries,其中包含一个值作为值.它可以通过以下几种方式创建地图:
使用不可变集合:
def createMap() = keys.map(key => key -> (1 to amount).toSet).toMap
Run Code Online (Sandbox Code Playgroud)
或者使用可变集合(请注意最后的两个转换选项):
def createMap() = {
val map = mutable.Map[String, mutable.Set[Int]]()
for (key <- keys) {
val set = map.getOrElseUpdate(key, mutable.Set())
for (i <- 1 to amount) {
set.add(i)
}
}
map.toMap.mapValues(_.toSet) // option #1
map.mapValues(_.toSet).toMap // option #2
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,可变#1代码创建了一个映射,toSet无论何时get调用(如果条目存在),它都会调用其值,这可能会导致显着的性能损失(取决于用例).
为什么会这样?如何避免这种情况?
mapValues只需返回一个地图视图,该视图将此地图的每个键映射到f(this(key)).生成的地图包装原始地图而不复制任何元素.
查看实现,mapValues返回一个MappedValues覆盖该get函数的实例:
def get(key: K) = self.get(key).map(f)
Run Code Online (Sandbox Code Playgroud)
如果要强制实现地图,请toMap在通话后mapValues拨打电话.就像你在#2中所做的那样!