S-JIS[2011-09-18] 変更履歴
Scala2.9で並列コレクション(parallel collections)が導入された。
|
Scala2.9で並列コレクションが導入された。
コレクションを並列化して別々のスレッドで実行する、という記述が非常に簡単に出来る。
通常の合計の例 |
Array(1,2,3,4,5).sum |
並列コレクションの例 |
Array(1,2,3,4,5).par.sum |
parによって生成された並列コレクションは、後は通常のコレクションと同様のメソッドを呼び出して操作(処理)する。
このとき、自動的に稼動マシン上のCPUのコア数に応じたスレッドに分けて実行してくれる。
もちろん、並列化する為のコストはかかるので、件数(コレクションの要素数)が少ないと逆に遅くなる。
(4スレッドになったとしても単純に実行時間が1/4になるわけではないが、概ねそれに近くなる)
並列化できるスレッド数(プロセッサー数)は以下のようにして取得できる。
scala> scala.collection.parallel.availableProcessors res0: Int = 2
並列コレクションを生成するには、通常の(並列化されていない)コレクションからparメソッドを呼び出す。
逆に並列コレクションのseqメソッドを呼び出すと、並列化されていないコレクションが取得できる。
コレクション | 生成される 並列コレクション |
seqによる コレクション |
par生成時間 [ms] |
備考 (元コレクションの生成方法) |
---|---|---|---|---|
Range | ParRange | Range | 0 | Range(1, N) |
Array | ParArray | ArraySeq | 74 | Array.range(1, N) |
List | ParVector | Vector | 547 | List.range(1, N) |
Vector | ParVector | Vector | 0 | Vector.range(1, N) |
Map | ParMap | Map | 0 | list.zipWithIndex.toMap |
Set | ParSet | Set | 0 | list.toSet |
生成時間は、100万要素のコレクションを生成しておき、そのparの実行時間を簡易benchmarkを使って測定したもの。
(Scala2.9.1・JDK1.6.0_22・WindowsXP)
val N = 100*10000+1 val list = List.range(1, N) benchmark(10){ list.par }.report
生成時間「0」は、16ms未満という意味。つまり並列コレクションの生成コストがほとんどかからない。
Array(配列)は可変コレクションなので、生成の際にデータコピーされていて多少時間がかかっているものと思われる。
List(リスト)は全データを走査しないとスレッド毎に分割したリストを作成できないはずなので、その走査に時間がかかっているものと思われる。
Listの場合は、並列コレクション生成の為の走査に時間をかけるくらいなら、直接やりたい操作(処理)を実行する方が速いかも(苦笑)