Parallel Collectionのベンチマークやってみた
xuwei_kさんが面白そうなこと(scala2.9のparallel collection の benchmark をしてみた)をやってたので、ちょっと自分でもやってみることにした。
さてscalaを起動
あとJVMの引数のXmx を 4096M にしてます
との事なので自分もそれに倣う。Xmsも指定すべきか分からなかったので、意味もなく1024にしてみた。4096にしとけばよかったかもしれないけどまあよしとする。
ちなみにメモリのサイズ指定の仕方はここを参考に。
>set "JAVA_OPTS=-Xmx4096M -Xms1024M" >scala Welcome to Scala version 2.10.0.r0-b20110322031631 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_21). Type in expressions to have them evaluated. Type :help for more information. scala> scala.collection.parallel.availableProcessors res0: Int = 8
さて実行!
scala> import collection.parallel import collection.parallel scala> def benchmark(times: Int)(f: =>Any) = new scala.testing.Benchmark{ def run = f }.runBenchmark(times) benchmark: (times: Int)(f: => Any)List[Long] scala> implicit def benchmark2report(list:List[Long]) = new { val average = (list.sum - list.max - list.min).toDouble / (list.size-2) } benchmark2report: (list: List[Long])java.lang.Object{val average: Double} scala> def test(listSize:Int){ | println("--------------" + listSize + "---------------") | val normal = 1L to listSize toList //???ハ?フList?ツ?ュ?? | val parSeq = normal toParSeq //?v?f?ェ?ッ?カparalell?ナ???ツ?ュ?? | val normalResult = benchmark(5)( normal.reduceLeft(_ + _) ) | //reduce?ニ?「?、?フ?ェ?Aparalell?ネcollection?ノ?オ?ゥ?ネ?「???\?b?h?ナ?A | //???ナ?X???b?h?カ?ャ?オ?ェ???オ?ト?????オ?ト?????オ?「 | val parSeqResult = benchmark(5)( parSeq.reduce(_ + _) ) | println( normalResult , parSeqResult , parSeqResult.average / normalResult.average ) | } <console>:13: error: value toParSeq is not a member of List[Long] val parSeq = normal toParSeq //?v?f?ェ?ッ?カparalell?ナ???ツ?ュ??
toParSeqていうのが無いというエラー。2.9と2.10で仕様が変わってるっぽい。代わりにParallelizableというtraitのparメソッドを使えばOKっぽい。
ちなみに、Windowsのコマンドプロンプトにコピペしたので文字化けしているけど気にしない。
scala> def test(listSize:Int){ | println("--------------" + listSize + "---------------") | val normal = 1L to listSize toList //???ハ?フList?ツ?ュ?? | val parSeq = normal par //?v?f?ェ?ッ?カparalell?ナ???ツ?ュ?? | val normalResult = benchmark(5)( normal.reduceLeft(_ + _) ) | //reduce?ニ?「?、?フ?ェ?Aparalell?ネcollection?ノ?オ?ゥ?ネ?「???\?b?h?ナ?A | //???ナ?X???b?h?カ?ャ?オ?ェ???オ?ト?????オ?ト?????オ?「 | val parSeqResult = benchmark(5)( parSeq.reduce(_ + _) ) | println( normalResult , parSeqResult , parSeqResult.average / normalResult.average ) | } test: (listSize: Int)Unit
これでOK。
ようやく実行
scala> 2000000 to 20000000 by 2000000 foreach test --------------2000000--------------- (List(42, 31, 31, 31, 30),List(47, 16, 15, 14, 15),0.4946236559139785) --------------4000000--------------- (List(279, 63, 61, 61, 59),List(27, 28, 28, 28, 28),0.4540540540540541) --------------6000000--------------- (List(98, 90, 90, 92, 94),List(42, 42, 41, 44, 41),0.45289855072463764) --------------8000000--------------- (List(2178, 131, 128, 129, 131),List(48, 49, 46, 52, 47),0.3682864450127877) --------------10000000--------------- (List(149, 150, 148, 150, 147),List(83, 82, 79, 81, 95),0.5503355704697986) --------------12000000--------------- (List(190, 176, 177, 181, 187),List(80, 79, 88, 89, 89),0.47155963302752296) --------------14000000--------------- (List(219, 227, 220, 217, 213),List(106, 127, 109, 107, 105),0.49085365853658536) --------------16000000--------------- (List(292, 244, 243, 244, 247),List(126, 124, 131, 124, 124),0.508843537414966) --------------18000000--------------- (List(325, 267, 273, 279, 281),List(147, 143, 146, 154, 157),0.5366146458583433) --------------20000000--------------- (List(340, 327, 298, 299, 302),List(138, 140, 140, 141, 146),0.45366379310344834)