Parallel Collectionのベンチマークやってみました
Scala2.9で導入されるParallel Collectionについてベンチマークがなされており、Scala2.9を触ったことなかったのでこれに乗じてみようかと。
scala2.9のparallel collection の benchmark をしてみた - scalaとか・・・
Parallel Collectionのベンチマークやってみた - k4200’s notes and thoughts
準備
Scalaのバージョンを簡単に切り替えられる"svm"ってヤツ作った (冷やし中華終わりました) - ゆるよろ・オブ・ザ・( ;゚皿゚)ノシΣ フィンギィィーーッ!!! 日記
Scalaのインストールに@yuroyoroさんのsvmを利用してます。
svm update-latest
これでnightly-buildをダウンロードしてくれます。DL後にcurrentを切り替えるか聞かれるのでyesで。
> scala -version Scala code runner version 2.9.0.r24471-b20110317020039 -- Copyright 2002-2011, LAMP/EPFL
2.9入りました。
JAVA_OPTSは例に習って以下を設定
export JAVA_OPTS='-Xmx4G -Xms1G'
PCスペック
つい最近新調しました。初MacですがMac使いやすいですね。
このPCの性能を見てみたかったとかそういうこともあります。
ソース
元のものをobjectに突っ込んでコンパイルできるようにしただけです。
object ParBench { def benchmark(times: Int)(f: =>Any) = new scala.testing.Benchmark{ def run = f }.runBenchmark(times) implicit def benchmark2report(list:List[Long]) = new { val average = (list.sum - list.max - list.min).toDouble / (list.size-2) } def test(listSize:Int){ println("--------------" + listSize + "---------------") val normal = 1L to listSize toList //普通のListつくる val parSeq = normal toParSeq //要素が同じparalell版をつくる val normalResult = benchmark(5)( normal.reduceLeft(_ + _) ) //reduceというのが、paralellなcollectionにしかないメソッドで、 //内部でスレッド生成し分割して処理してるらしい val parSeqResult = benchmark(5)( parSeq.reduce(_ + _) ) println( normalResult , parSeqResult , parSeqResult.average / normalResult.average ) } def main(args: Array[String]) { println("availableProcessors: " + scala.collection.parallel.availableProcessors) 2000000 to 20000000 by 2000000 foreach test } }
これをファイルに保存してscalac。
さっそく実行
ファンがガンガン回ってPC酷使してる感じがしますね。
availableProcessors: 4 --------------2000000--------------- (List(39, 24, 13, 13, 14),List(42, 12, 12, 12, 12),0.7058823529411765) --------------4000000--------------- (List(72, 28, 29, 29, 28),List(25, 25, 26, 24, 27),0.883720930232558) --------------6000000--------------- (List(132, 43, 43, 44, 44),List(41, 39, 41, 40, 40),0.9236641221374047) --------------8000000--------------- (List(165, 57, 58, 57, 57),List(52, 52, 51, 51, 52),0.9011627906976744) --------------10000000--------------- (List(154, 80, 85, 84, 83),List(70, 71, 70, 70, 70),0.8333333333333334) --------------12000000--------------- (List(183, 97, 99, 103, 102),List(85, 88, 87, 85, 86),0.8486842105263158) --------------14000000--------------- (List(212, 120, 118, 118, 118),List(100, 99, 98, 100, 100),0.8398876404494382) --------------16000000--------------- (List(252, 140, 140, 140, 138),List(114, 117, 118, 117, 116),0.8333333333333334) --------------18000000--------------- (List(181, 158, 158, 158, 158),List(135, 133, 137, 135, 132),0.8502109704641351) --------------20000000--------------- (List(195, 173, 176, 171, 174),List(149, 144, 146, 150, 148),0.8470363288718928)
あれ?
0.8台半ばで期待したほど早くならない。
REPLで実行
元と違うのはscalacでコンパイルして実行しているとこ、なのでREPLで実行してみる。
Welcome to Scala version 2.9.0.r24471-b20110317020039 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_24). Type in expressions to have them evaluated. Type :help for more information. scala> :load ParBench.scala Loading ParBench.scala... defined module ParBench availableProcessors: 4 --------------2000000--------------- (List(29, 23, 23, 23, 23),List(42, 11, 11, 10, 10),0.46376811594202894) --------------4000000--------------- (List(101, 47, 47, 47, 49),List(28, 26, 26, 27, 27),0.5594405594405595) --------------6000000--------------- (List(175, 74, 72, 73, 72),List(40, 41, 42, 41, 40),0.5570776255707762) --------------8000000--------------- (List(208, 96, 96, 96, 96),List(53, 54, 54, 52, 53),0.5555555555555556) --------------10000000--------------- (List(221, 146, 142, 145, 142),List(73, 70, 72, 71, 70),0.4919168591224018) --------------12000000--------------- (List(272, 176, 172, 178, 174),List(87, 89, 86, 88, 86),0.4943181818181818) --------------14000000--------------- (List(299, 200, 204, 204, 194),List(102, 100, 100, 101, 100),0.49506578947368424) --------------16000000--------------- (List(367, 245, 235, 231, 243),List(118, 119, 117, 119, 114),0.4896265560165975) --------------18000000--------------- (List(309, 268, 273, 271, 271),List(136, 135, 138, 136, 134),0.4993865030674846) --------------20000000--------------- (List(336, 306, 305, 304, 313),List(149, 149, 149, 150, 149),0.4837662337662338)
0.5前後で倍率はよくなってるけどこれは……
並べると
--------------20000000--------------- (List(195, 173, 176, 171, 174),List(149, 144, 146, 150, 148),0.8470363288718928) // コンパイル (List(336, 306, 305, 304, 313),List(149, 149, 149, 150, 149),0.4837662337662338) // REPL
parallelの速度は変わってないですが、normalはコンパイルするとかなり速度が向上してる。
これはJITコンパイラが頑張ってくれてるということかな。
Server VM
そういえばREPLはServer VMで起動してますね。
という訳でJAVA_OPTSに -server を追加してみて再度実行。
export JAVA_OPTS='-server -Xmx4G -Xms1G'
availableProcessors: 4 --------------2000000--------------- (List(39, 13, 12, 13, 14),List(39, 10, 10, 10, 9),0.75) --------------4000000--------------- (List(453, 30, 42, 30, 30),List(22, 21, 22, 22, 22),0.6470588235294118) --------------6000000--------------- (List(93, 41, 41, 41, 41),List(29, 28, 29, 28, 29),0.6991869918699187) --------------8000000--------------- (List(2082, 60, 61, 61, 59),List(42, 42, 42, 42, 42),0.6923076923076923) --------------10000000--------------- (List(2632, 74, 75, 74, 74),List(52, 52, 52, 51, 51),0.695067264573991) --------------12000000--------------- (List(147, 84, 85, 85, 83),List(58, 56, 58, 57, 57),0.6771653543307087) --------------14000000--------------- (List(148, 100, 98, 99, 100),List(67, 67, 67, 67, 66),0.6722408026755853) --------------16000000--------------- (List(3940, 121, 125, 122, 123),List(82, 81, 82, 82, 83),0.6648648648648648) --------------18000000--------------- (List(4628, 138, 139, 137, 138),List(95, 95, 95, 95, 95),0.6867469879518072) --------------20000000--------------- (List(3829, 152, 151, 149, 150),List(123, 124, 119, 119, 119),0.7969094922737306)
--------------20000000--------------- (List(195, 173, 176, 171, 174),List(149, 144, 146, 150, 148),0.8470363288718928) // コンパイル (List(336, 306, 305, 304, 313),List(149, 149, 149, 150, 149),0.4837662337662338) // REPL (List(3829, 152, 151, 149, 150),List(123, 124, 119, 119, 119),0.7969094922737306) // コンパイル(Server VM)
更に高速化しました。
normalの最初で極端に遅くなるのはGCっぽいかな?-Xmsは-Xmxと同じにした方がいいかも。REPLではここまでひどい数値は出ないので他に何かあるんだと思いますが。