2016-11-16 9 views
0

次のコードは、実際のケースでは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() 
} 

問題はmapValuesSortedMapのための良好な性能を持っていながら、結果は実際のコレクションが、ビューではなく、そのように、それはシリアライズすることができないです。キーと値の両方をマッピングする単純なソリューションが機能しますが、ツリー表現が再構築されると遅くなります。mapはキーを変更していません。

SortedMap.mapValuesの代わりに、シリアル化可能な結果が出力されますか?

+0

'mapValues'の上に' map'というアイデンティティを 'map'するとどうなりますか:' sMapValues.map(identity) '、まだ再構築されますか? – Rumoku

+0

'mapValues(f)'が遅いと思われるのは、 'f'が遅れて適用されるためです。シリアライズ時には実際に 'f'を適用する必要があるので、' oos.writeObject(sMapValues.toSeq) 'または' val sMapValues = s.mapValuesのいずれかの段階で 'toSeq'を使ってシリアライズすることもできます(f).toSeq'とする。 – Carsten

答えて

0

変換してみてください。

val sMapValues = s.transform((_,v) => f(v)) 

キーと値を変換ラムダに設けられているが、結果は値のみに適用され、キーは変更されません。

+0

私はデバッガでこれをチェックしましたが、有望に見えます。 'transform'は完全な再構築を行います:' for((key、value)< - this)b + =((key、f(key、value))) ' – Suma

関連する問題