Ruby1.9のfiberのかっこいい使い方

3,429 views

Published on

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,429
On SlideShare
0
From Embeds
0
Number of Embeds
39
Actions
Shares
0
Downloads
14
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

Ruby1.9のfiberのかっこいい使い方

  1. 1. Ruby1.9のFiberとクロージャのかっこいい使い方<br />Rubyist九州<br />山崎重一郎<br />
  2. 2. まず、関数、クロージャ、継続の気持ちを説明してみます<br />マインド<br />Rubyではどうなっているのか?<br />          <br />
  3. 3. 関数とマインド<br />関数はいつも上から目線<br /> 自分自身の心が行っていることを幽体離脱して外から眺める感じ<br />ああして<br />こうして<br />こうなったら<br />こうして<br />関数の定義<br />
  4. 4. 0マインド<br />「何もない」状態を考えてみましょう<br />0 = φ = {}<br />{}<br />
  5. 5. 1マインド<br />「何もない」と思っている自分を見ている自分<br /> 1 = {φ}<br />{}<br />
  6. 6. 2マインド<br />1マインドの自分を見ている自分<br /> 2 = {φ,{φ}}<br />
  7. 7. 3マインド<br />2マインドの自分を見ている自分<br /> 3 = {φ,{φ},{φ,{φ}}}<br />
  8. 8. ωマインド<br />これってずっと無限にできるよねと思っている自分<br /> ω = {φ,{φ},{φ,{φ}},...}<br />...<br /> 「我はαでありωである」<br />     ヨハネの黙示録<br />
  9. 9. ω+1マインド<br />「これってずっと無限にできるよねと思っている自分」を見ている自分<br /> ω+1 = {ω}<br />
  10. 10. ω+ωマインド<br />ωマインドを対象にした対象化もまた無限にできるよねと思っている自分<br /><ul><li> ω+1 = {ω,{ω},{ω,{ω}},...}</li></ul>...<br />
  11. 11. まだまだ<br />3ωマインド<br />ω×ωマインド<br />ωωマインド<br />....<br />★でも、ずっとずっとやると精神を病みます<br />
  12. 12. ωマインドの関数定義<br />λを使うことがωマインドの例<br />-> x { ... }<br />階乗の再帰的定義<br />fact = -> n {n==0 ? 1 : n*fact[n-1]}<br />★下のように書く方が Ruby っぽいけど<br />fact = -> x {(1..x).reduce(:*)}<br />
  13. 13. ω+ωマインドの関数定義<br />λを二つ使うとω+ω<br />-> x { -> y {...} }<br />組み合わせ関数(再帰なのですっごく遅い)<br />combi=->n{->r{r==1 ?n:(n==r ?1:combi[n-1][r-1]+combi[n-1][r])}}<br />
  14. 14. でも有限のマインドも大切<br />クロージャ:上から目線でつくった状態<br />ωマインドの視点から -> nマインド(状態)を見る<br />ファイバー:継続、ジェネレータ<br />ジェネレータ: n マインドから ωマインドを見る その逆も<br />
  15. 15. 関数とクロージャ<br />関数の独立変数と係数<br /> f(x) = a*x<br /> aは係数でxは独立変数?<br /><ul><li>係数のa をω+ωの視点から見下ろして定義</li></ul>fa= ->a {->x {a*x}}<br />で、aに何かの値を束縛したωな関数をつくる<br /> fa= ->a {->x {a*x}}<br />> f=fa[2]<br />> f[3]<br />=> 6<br />> eval('a',f.binding)<br />=> 2<br />
  16. 16. 関数のメモ化<br />関数には時間の概念がない<br />でも、もう一つ上のωの視点から見おろせば状態が作れる<br />組み合わせ関数のメモ化<br />combi_memo= ->m { ->n {m[n]||={}; ->r {m[n][r]||=combi[n][r]}}}<br />> cm=combi_memo[{}]<br />> cm[3][2]<br />=> 3<br />> cm[30][7]<br />=> 2035800<br />> eval('m',cm.binding)<br />=> {3=>{2=>3}, 30=>{7=>2035800}}<br />
  17. 17. Fiber <br />f=Fiber.new{|x|<br />puts '最初'<br />Fiber.yield<br /> puts x<br />y=Fiber.yield<br /> puts y<br />}<br />> f.resume 3 #new メソッドへ<br />最初<br />=> nil<br />> f.resume #yield メソッドへ<br />3<br />=> nil<br />> f.resume7 #yield メソッドへ<br />7<br />=> nil<br />> f.resume<br />FiberError: dead fiber called<br />継続、軽量スレッド<br />Fiber.new {|x|...}<br />ファイバーの生成<br />Fiver.yield(obj)<br />親のコンテクストに行く<br />resume(obj) メソッド<br />子供のコンテクストに行く<br />(途中でとまっていた処理を継続)<br />
  18. 18. Fiber によるジェネレータ<br />nマインドとωマインドを行き来する<br />無限ループでデータを無限に生成するプログラムの最初のn要素<br />自然数ジェネレータ<br />num= -> a {loop {a+=1}}<br />> num[0]<br />... 無限ループ〜<br />無限集合を素直に生成しているんだけどね<br />ファイバーにした自然数ジェネレータ<br />n = Fiber.new{|a|loop{Fiber.yielda+=1}}<br />無限集合の最初の5個だけ取り出す<br />(Haskellみたいでかっこいい!)<br />> 5.times {puts n.resume 0}<br />1<br />2<br />3<br />4<br />5<br />=> 5<br />
  19. 19. Fiber によるジェネレータ<br />フィボナッチ数列バージョン!<br />フィボナッチ数列ジェネレータ<br />fib = -> x {a,b=x<br /> loop {a; a,b=b,a+b}}<br />>fib[[0,1]]<br />... 無限ループ〜<br />フィボナッチ数列を素直に生成している<br />ファイバーにしたフィボナッチ数列ジェネレータ<br />f = Fiber.new{|x| a,b=x<br /> loop {Fiber.yielda; a,b=b,a+b}}<br />無限集合の最初の5個だけ取り出す<br />> 5.times {puts f.resume [0,1]}<br />0<br />1<br />1<br />2<br />3<br />=> 5<br />もっとHaskellチックにこんなのもいいかも!<br />deff.take(n) n.times {puts self.resume} end<br />> f.take 10<br />
  20. 20. Fiberによるコルーチンで軽量イベント駆動マシン<br />初期のMacintosh OS<br />多数のコルーチンの集合体でできていた<br />(すっごく軽量なスレッドみたいなもの)<br />Macintosh 128K<br />8MHz<br />128Kb<br />コルーチン<br />コルーチン<br />コルーチン<br />コルーチン<br />操作による<br />イベント<br />実際のメモリ<br />コルーチン<br />ビットマップ<br />への表示など<br />
  21. 21. Fiberによるコルーチンで軽量イベント駆動マシン<br />Rails 3.2 からPjaxが標準に<br />WebサーバにFiberプールで軽量スレッド<br />メモリ節約、起動/再起動の高速化<br />コルーチン<br />コルーチン<br />Pjax<br />ブラウザ<br />コルーチン<br />コルーチン<br />操作による<br />イベント<br />Fiber対応Webサーバ<br />unicornとかGoliathとか<br />コルーチン<br />ブラウザへの<br />表示変更<br />
  22. 22. FiberとThreadの比較<br />出典:Ruby Fibers Vs Ruby Threads<br />http://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html<br />
  23. 23. Fiberによるリアルタイム処理<br />次回にね!<br />

×