在我编写的Scala程序中,我有一个scala.collection.Map
,它将字符串映射到一些计算值(详细地说是Map[String, (Double, immutable.Map[String, Double], Double)]
- 我知道这很丑陋(应该)并将被包裹)。现在,如果我这样做:
stats.map { case(c, (prior, pwc, denom)) => {
println(c)
...
}
}
打印大约50倍c
的值大约需要30秒! println
只是一个测试声明 - 我需要的实际计算甚至更慢(我在完全沉默1分钟后中止)。但是,如果我这样做:
stats.mapValues { case (prior, pwc, denom) => {
println(prior)
...
}
}
我不会遇到这些性能问题......任何人都可以解释为什么会这样吗?我没有遵循一些重要的Scala指南吗?
感谢您的帮助!
修改
我进一步调查了这种行为。我的猜测是瓶颈来自Map
数据结构中的访问。如果我执行以下操作,则会遇到相同的性能问题:
classes.foreach{c => {
println(c)
val ps = stats(c)
}
}
此处classes
是List[String]
,用于在外部存储地图的键。如果无法访问stats(c)
,则不会发生性能损失。
答案 0 :(得分:3)
mapValues
实际上会在原始地图上返回一个视图,这可能会导致意外的性能问题。来自this博文:
...这里有一个问题:map和mapValues在不那么微妙的情况下是不同的 办法。与map不同,mapValues返回原始地图上的视图。这个 视图包含对原始地图和原始地图的引用 转换函数(这里(_ + 1))。每次返回地图 (查看)被查询,原始地图首先被查询和 在结果上调用转换函数。
我建议阅读该帖子的其余部分以获取更多详细信息。