S-JIS[2011-09-18] 変更履歴

Scala 並列コレクション

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の場合は、並列コレクション生成の為の走査に時間をかけるくらいなら、直接やりたい操作(処理)を実行する方が速いかも(苦笑)


コレクションへ戻る / Scala目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま