Monday, November 8, 2010

scalaでactor使ってparallel map その2

-----------
これもシングルスレッドだ。パラレルじゃない。Futureを使わないFork-Joinは再チャレンジする(11/8追記)
----------

前回の実装はイケてない。
pmapの関数定義の結果型がList[Any](実際はList[List[T]])だった。
map的にはList[T]を返した方が自然だよな。

ということで改良してみた。

  1. import scala.actors.Actor._  
  2.   
  3. @SuppressWarnings(Array("unchecked"))  
  4. def pmap[T, U](xs: List[T], n: Int)(fun: T => U): List[U] = {  
  5.   
  6.   def divide(n: Int, xs: List[T]): List[List[T]] = {  
  7.     val size = xs.size / n  
  8.     def r(ys: List[T], acc: List[List[T]]): List[List[T]] = {  
  9.       if(ys.size < size) (acc.head ::: ys) :: acc.tail  
  10.       else{  
  11.         val splitted = ys.splitAt(size)  
  12.         r(splitted._2, splitted._1 :: acc)  
  13.       }  
  14.     }  
  15.     r(xs, Nil).reverse  
  16.   }  
  17.   
  18.   val mapped: List[List[U]]  = divide(n, xs).map{ l =>  
  19.     val a = actor { receive { case _ => reply(l.map(fun(_))) } }  
  20.     a !? "s" match {  
  21.       case l: List[U] => l  
  22.       case _ => Nil  
  23.     }  
  24.   }  
  25.   
  26.   mapped.flatten  
  27. }  
  28.   
  29. val l = (1 to 100).toList  
  30. val result = pmap[Int, Int](l, 4)(_ + 1)  
  31.   
  32. println(result)  

実行すると、
warning: non variable type-argument U in type pattern List[U] is unchecked since it is eliminated by erasure
case l: List[U] => l
^
one warning found
List(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101)
となる。

erasureによって型Uが消されてるからcase List[U]がU以外でもマッチしてあぶねーよ、っていわれてる。
@SuppressWarnings(Array("unchecked"))書いても警告がでるのね。
無視スリゃいいんだろうけど気持ち悪い。

scalaでactor使ってparallel map その3 - Futures編に続く。

No comments:

Post a Comment