次のコードは、実際のケースではSortedMap
のキーがJoda DateTime
であり、マップに数千の要素が含まれているという問題を示しています。SortedMap.mapValuesの高速代替
import java.io.{ByteArrayOutputStream, ObjectOutputStream}
import scala.collection.immutable.SortedMap
object Main extends App {
val s = SortedMap(1 -> "A", 2 -> "B", 3 -> "C")
def f(s: String) = s
val sMap = s.map(kv => kv._1 -> f(kv._2)) // slow: rebuilds Map, as keys could change
val sMapValues = s.mapValues(f) // fast, but creates a view only
val so = new ByteArrayOutputStream
val oos = new ObjectOutputStream(so)
oos.writeObject(s) // works
oos.writeObject(sMap) // works
oos.writeObject(sMapValues) // does not work - view only
oos.close()
so.close()
}
問題はmapValues
がSortedMap
のための良好な性能を持っていながら、結果は実際のコレクションが、ビューではなく、そのように、それはシリアライズすることができないです。キーと値の両方をマッピングする単純なソリューションが機能しますが、ツリー表現が再構築されると遅くなります。map
はキーを変更していません。
SortedMap.mapValues
の代わりに、シリアル化可能な結果が出力されますか?
'mapValues'の上に' map'というアイデンティティを 'map'するとどうなりますか:' sMapValues.map(identity) '、まだ再構築されますか? – Rumoku
'mapValues(f)'が遅いと思われるのは、 'f'が遅れて適用されるためです。シリアライズ時には実際に 'f'を適用する必要があるので、' oos.writeObject(sMapValues.toSeq) 'または' val sMapValues = s.mapValuesのいずれかの段階で 'toSeq'を使ってシリアライズすることもできます(f).toSeq'とする。 – Carsten