ジャパネットQB

2011/02/24 at G*ワークショップ
ジャパネットQB

    GParsで
 並行プログラミング
一部元ネタを知らないと
楽しめないところがございますが、
  ご了承願います m(_ _)m
こんばんは、
ジャパネットQBの時間だよ。
  今日紹介する商品は、
  GParsだよ、まどか。
お前、誰よ
名前:キュゥべえ(QB)
出身:『魔法少女まどか☆マギカ』(MBS,TBS,CBC)
特徴:腹黒
口癖:「僕と契約してよ。」
ねぇ QB、

GParsって何なの?
GPars(Groovy Parallel Systems)
   ってね、Groovyベースの
並行処理ライブラリのことだよ。
近年のCPUの進化って、
   クロックアップよりも
マルチコア・メニーコア化の方が
     中心だよね。
プログラミングも
 マルチコアを活用すべく、
  並行プログラミングが
意識されるようになったんだ。
まどかは、
並行プログラミングって
   どうしてる?
えっ…
 java.lang.Threadと
java.lang.Runnableと
 synchronizedしか…
私は、
java.util.concurrentパッケージの
  ExecutorServiceやFuture、
     CountDownLatchね。
でもね、Java APIだけで
 並行プログラミングって
なかなか難しいと思わない?
そこで、GParsの出番さ。
GParsは、様々な言語の
並行モデルや調整モデルを
 取り込んでいるんだ。
・JavaのExecutorやFork/Join
・ErlangやScalaのActor
・ClojureのAgent
・OzのDataflow Variable
これらのモデルを
  Groovyをベースに
使いやすく書きやすいように
上手くDSL化してるんだ。
GParsのURLは
http://gpars.codehaus.org/
最新バージョンは0.11、
 昔はGParallelizerって
  呼ばれてたんだよ。
僕と契約してみたく...
GParsを使ってみたくなったでしょ?
えっ…
でも、インストールとか
   大変でしょ?
そんなことないよ。
 Groovy 1.8.0-beta-4から
GParsのライブラリがバンドル
 されるようになったんだ。
Groovyをインストールするだけで、
 GParsも使えるようになるんだ。
そんな説明だけでは、
 ピンと来ないわね。
じゃあ、簡単にだけど、
 GParsの持つ機能を
 いくつか紹介するね。
まず、並列コレクション。
 コレクションに対する操作を
並列に行うことができるんだ。
並列コレクション
import static groovyx.gpars.GParsPool.withPool

def nums = 1..100000
withPool(5) {
    def squares = nums.
        collectParallel{ it ** 2 }.
        grepParallel{ it % 7 == it % 5 }.
        grepParallel{ it % 3 == 0 }
    println squares[0..3] + "..." + squares[-3..-1]
    assert squares[0..3] == [36, 144, 1089, 1296]
}
さっきの例は、
もう少し簡潔に書けるんだ。
並列コレクション
import static groovyx.gpars.GParsPool.withPool

def nums = 1..100000
withPool(5) {
    def squares = nums.parallel.
        map{ it ** 2 }.
        filter{ it % 7 == it % 5 }.
        filter{ it % 3 == 0 }.
        collection
    println squares[0..3] + "..." + squares[-3..-1]
    assert squares[0..3] == [36, 144, 1089, 1296]
}
次は、Fork/Join。
 分割統治的な処理を
することができるんだ。
Fork/Join
import static groovyx.gpars.GParsPool.withPool
import static groovyx.gpars.GParsPool.runForkJoin

def quicksort(numbers) {
    withPool {
        runForkJoin(0, numbers) {index, list ->
            def groups = list.groupBy {
                it <=> list[list.size().intdiv(2)]}
            if ((list.size() < 2) || (groups.size() == 1)) {
                return [index: index, list: list.clone()]
            }
            (-1..1).each {
                forkOffChild(it, groups[it] ?: [])}
            return [index: index,
                    list: childrenResults.sort
                                {it.index}.sum {it.list}]
        }.list
    }
}
次は、Closureの非同期実行。
   Closureを簡単に
  非同期実行するんだ。
Closureの非同期実行
import static groovyx.gpars.GParsExecutorsPool.withPool

withPool {
    // 同期
    assert 6 == {it * 2}.call(3)
    // 非同期
    assert 6 == {it * 2}.callAsync(3).get()
}
次は、Actor。
 メールボックスの
メッセージを使用する
軽量のプロセスだね。
Actor
import static groovyx.gpars.actor.Actors.actor

def decryptor = actor {
    react {message ->
        reply message.reverse()
    }
}
def console = actor {
    react {
        println 'Decrypted message: ' + it
    }
}

decryptor.send 'lellarap si yvoorG', console
console.join()
次は、Agent。
     オブジェクトに
スレッドセーフにアクセスするための
     仕組みだよ。
Agent
import static groovyx.gpars.agent.Agent

def jugMembers = new Agent<List<String>>(['Me'])

jugMembers.send {it.add 'James'}

final Thread t1 = Thread.start {
    jugMembers << {it.add 'Joe'}
}

final Thread t2 = Thread.start {
    jugMembers {it.add 'Dave'}
    jugMembers {it.add 'Alice'}
}

[t1, t2]*.join()
println jugMembers.val
jugMembers.valAsync {println "Current members: $it"}

jugMembers.await()
最後は、Dataflow変数。
  変数へのバインドで
処理を協調的に行うんだ。
Dataflow変数
import static groovyx.gpars.dataflow.DataFlowVariable
import static groovyx.gpars.dataflow.DataFlow.task

final def x = new DataFlowVariable()
final def y = new DataFlowVariable()
final def z = new DataFlowVariable()

task {
    z << x.val + y.val
    println "Result: ${z.val}"
}

task {
    x << 10
}

task {
    y << 5
}
ねぇ、どうだった、まどか?
 並行プログラミングをする時は
GParsを使ってみるといいかも。
お約束
でも・・・
高いんでしょ?
Apache 2 ライセンスの
 オープンソースだよ。
だから、僕と契約して、
 魔法少女になってよ。
Groovy使いになってよ。
でも、
クーリングオフはできないからね。
ジャパネットQB

   完

ジャパネットQB GPars