狠狠撸

狠狠撸Share a Scribd company logo
PP.js
Pseudo - Parallel
Passing - Procedure
Pretty - Promise

VoQn
http://voqn.github.com/pp.js
Who?
? VoQn :: ウェッブケー UI デザイナー
? UI / UX の研究職 @Dwango
? meso の下で「おい仕事しろクズ」って
  言われながら仕事サボってる
? Scheme > Haskell > Ruby の順で好き
? Javascript は「好きだけど嫌いです」
? 自己紹介させるより Google に聞いた
  方が早い系の人です
Agenda
? pp.js ?
? Prologue/Problem
? Pseudo-Parallel
? Presto Processing   (faster than async.js)


? etc...
pp.js ?
? Pianissimo  (ピアニッシモ)


? CoffeeScript × grunt.js  で開発


? Travis CI × buster.js   で継続的テスト


? Promise/A (CommonJS) 実装
  jsDeferred, jQuery.Deferred   のコンパチ


? async.js   の歯がゆい部分を解決

? 目標はゲームエンジンに本格的に導入できる
  レベルの汎用非同期処理ライブラリ
Prologue
? もともとは macchiato.js で
  非同期自動テストのサポートを
 やろうとしていた
? そこでや、国産 js ライブラリである
  async
        node で知名度の高い

 jsDeferred などを参考にしながら
 js での非同期処理ユーティリティを
 書いてみたりするうちに、ある事に気づいた
macchiato.js
http://voqn.github.com/macchiato
macchiato.js
http://voqn.github.com/macchiato
Problem
? async.js 普通に非同期じゃない件
? 非同期処理ライブラリのほとんどが
  発火時にユーザーイベント
 ブロックしてる件
? 詳しくは以下↓
 Async.js は自動的に非同期処理や
 並列処理にしてくれるライブラリじゃないよ
 http://qiita.com/items/c68e6472029ebd8b69e8
Is async.js async?
sqMapped = []

async.map [1..1e6] # iterable
, (value, next) -> # iteration
  next null, value * value
, (error, result) -> # callback
  sqMapped = result

# この時点で async.map が全て終わるまで
# 以下の処理に進めない
console.log sqMapped # 1, 4, 9 .. 普通に出力
async.js is sync
? 非同期処理「を」扱いやすくする
  ユーティリティでしかない
? 普通に使えばユーザーイベントをブロック
? ブロックしないようにするのにはそれなり
  というか、かなりの工夫がいる
? series (eachSeries, reduce(Right)) 系は
  _人人 人人 人人 人人 人人 人_
  > 突然のスタックオーバーフロー <
   ̄Y^Y^Y^YY^Y^Y^YY^Y^Y^Y ̄
Pseudo-Parallel
? node-fibers もコルーチン提供であって
  “並列”処理ではない
? 適切に長時間かかる処理を分割して、
  「別の処理が割り込める」擬似的な並列化を
 やってみた

? これを擬似並列 Pseudo-Para"el と呼んでいる
Trampoling


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
          pA

time slice tA



JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
          pA

time slice tA



JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
          pA

time slice tA



JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA

time slice tA



JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA

time slice tA
 ここでスレッドが一時的に開放され
  別のイベント処理が介入できる


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA                              pB
time slice tA                  time slice tB
 ここでスレッドが一時的に開放され
  別のイベント処理が介入できる


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA                              pB
time slice tA                  time slice tB
 ここでスレッドが一時的に開放され
  別のイベント処理が介入できる


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA                              pB
time slice tA                  time slice tB
 ここでスレッドが一時的に開放され
  別のイベント処理が介入できる


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampoling
   setTimeout(pA)

          pA                              pB
time slice tA                  time slice tB
 ここでスレッドが一時的に開放され                 pB が処理を終えたら pA の続き
  別のイベント処理が介入できる                 または別のイベント処理が介入される


JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側
http://www.infoq.com/jp/articles/js_multithread_2
Trampolining
 now = Date.now or () -> +new Date
 isFunction = (fn) -> typeof fn is‘function’

 # 簡単な実装例
 trampoline = (fn, ms) ->
   timeLimit = now() + ms
   while isFunction fn and now() < timeLimit
     fn = fn() # 関数の結果を自身に代入
   if isFunction fn # 処理が残ってる
     setTimeout trampoline, 0, fn, ms
     # node.js なら process.nextTick
   return
Asynchronous programming and continuation-passing style in JavaScript
http://www.2ality.com/2012/06/continuation-passing-style.html
Trampolining
    # 利用例
    countUpWith = (iterator, limit) ->
      i = 0
      trampoline () ->
        main = () ->
          return if ++i >= limit # undefined
          iterator i
          main # 自身を返すのがポイント
      , Math.floor 1000 / 60 # 60fps


Asynchronous programming and continuation-passing style in JavaScript
http://www.2ality.com/2012/06/continuation-passing-style.html
Sample
pp.readFile = pp.map (next, name) ->
  fs.readFile name, next
  # pp.map(iterator, callback, array_or_hash)

concatPrint = ppReadFile (error, result) ->
  console.log error or result.join‘n’
  # 部分適用された関数として利用できる

concatPrint [‘a.js’,‘b.js’,‘c.js’]


README かテストコード見た方が早い
https://github.com/VoQn/pp.js
Sample
cpsFib = (callback, n) ->
  pp.whilist (next, c) -> next null, c > 0
  , (next, c, a, b)    -> next null, c - 1, b, a + b
  , (error, c, a, b)   -> callback error, b
  , [n, 1, 0]
  # pp.whilist(test, iterator, callback, init_array)

printFib = (n) ->
  cpsFib (error, result) ->
    console.log error or result
  # 部分適用された関数として利用できる

printFib 10 #=> 55

  README かテストコード見た方が早い
  https://github.com/VoQn/pp.js
Presto Processing

? pp.js の各種 Collection API と
  async.js の同種の API でベンチマーク

? ソースコードは github に benchmark/ ディ
  レクトリで見れます
 https://github.com/VoQn/pp.js/tree/master/benchmark
Presto Processing
 ? 大きいデータを投げた時のベンチ比較
 ? [1..1.0e+7] の配列に7種のイテレータ
       time          memory           GC Full   発生


                x3
                                           なし
 pp   0:53.67        ?260MB    1/3   (10ms程の GC が都度)

                                         10秒以上
async 2:58.60   -    1100MB?    -
                                        ロックが数回
etc
? Q.なんで CoffeeScript で?
? A.Github Javascript StyleGuide
    見てバカにしたくなったから
JavaScript Styleguide :: Github
https://github.com/styleguide/javascript
JavaScript Styleguide :: Github
https://github.com/styleguide/javascript
JavaScript Styleguide :: Github
https://github.com/styleguide/javascript
JavaScript
  だって
言ってんだろが
Feature
? しかしながら npm ライブラリ等々
  coffee で書かれる事も今後増えるだろ
 うし、そちらの方が読めるという人が
 増えるのであれば選択の一つではある
? 近日中に v0.1.0 として npm に
  公開する予定 (MIT License)
? ブラウザ向け、 min.js も機能別に分
  割して提供できるようにする
Thank you
  ? fork, pull request,
    issue, code review
    ぜひお願いします
  ? macchiato も停滞気味なので
    叱咤激励お願いします




https://github.com/VoQn/pp.js

More Related Content

Introduction pp.js

  • 1. PP.js Pseudo - Parallel Passing - Procedure Pretty - Promise VoQn http://voqn.github.com/pp.js
  • 2. Who? ? VoQn :: ウェッブケー UI デザイナー ? UI / UX の研究職 @Dwango ? meso の下で「おい仕事しろクズ」って 言われながら仕事サボってる ? Scheme > Haskell > Ruby の順で好き ? Javascript は「好きだけど嫌いです」 ? 自己紹介させるより Google に聞いた 方が早い系の人です
  • 3. Agenda ? pp.js ? ? Prologue/Problem ? Pseudo-Parallel ? Presto Processing (faster than async.js) ? etc...
  • 4. pp.js ? ? Pianissimo (ピアニッシモ) ? CoffeeScript × grunt.js で開発 ? Travis CI × buster.js で継続的テスト ? Promise/A (CommonJS) 実装 jsDeferred, jQuery.Deferred のコンパチ ? async.js の歯がゆい部分を解決 ? 目標はゲームエンジンに本格的に導入できる レベルの汎用非同期処理ライブラリ
  • 5. Prologue ? もともとは macchiato.js で 非同期自動テストのサポートを やろうとしていた ? そこでや、国産 js ライブラリである async node で知名度の高い jsDeferred などを参考にしながら js での非同期処理ユーティリティを 書いてみたりするうちに、ある事に気づいた
  • 8. Problem ? async.js 普通に非同期じゃない件 ? 非同期処理ライブラリのほとんどが 発火時にユーザーイベント ブロックしてる件 ? 詳しくは以下↓ Async.js は自動的に非同期処理や 並列処理にしてくれるライブラリじゃないよ http://qiita.com/items/c68e6472029ebd8b69e8
  • 9. Is async.js async? sqMapped = [] async.map [1..1e6] # iterable , (value, next) -> # iteration next null, value * value , (error, result) -> # callback sqMapped = result # この時点で async.map が全て終わるまで # 以下の処理に進めない console.log sqMapped # 1, 4, 9 .. 普通に出力
  • 10. async.js is sync ? 非同期処理「を」扱いやすくする ユーティリティでしかない ? 普通に使えばユーザーイベントをブロック ? ブロックしないようにするのにはそれなり というか、かなりの工夫がいる ? series (eachSeries, reduce(Right)) 系は _人人 人人 人人 人人 人人 人_ > 突然のスタックオーバーフロー <  ̄Y^Y^Y^YY^Y^Y^YY^Y^Y^Y ̄
  • 11. Pseudo-Parallel ? node-fibers もコルーチン提供であって “並列”処理ではない ? 適切に長時間かかる処理を分割して、 「別の処理が割り込める」擬似的な並列化を やってみた ? これを擬似並列 Pseudo-Para"el と呼んでいる
  • 13. Trampoling pA time slice tA JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 14. Trampoling pA time slice tA JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 15. Trampoling pA time slice tA JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 16. Trampoling setTimeout(pA) pA time slice tA JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 17. Trampoling setTimeout(pA) pA time slice tA ここでスレッドが一時的に開放され 別のイベント処理が介入できる JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 18. Trampoling setTimeout(pA) pA pB time slice tA time slice tB ここでスレッドが一時的に開放され 別のイベント処理が介入できる JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 19. Trampoling setTimeout(pA) pA pB time slice tA time slice tB ここでスレッドが一時的に開放され 別のイベント処理が介入できる JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 20. Trampoling setTimeout(pA) pA pB time slice tA time slice tB ここでスレッドが一時的に開放され 別のイベント処理が介入できる JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 21. Trampoling setTimeout(pA) pA pB time slice tA time slice tB ここでスレッドが一時的に開放され pB が処理を終えたら pA の続き 別のイベント処理が介入できる または別のイベント処理が介入される JavaScriptによるマルチスレッドの実現-Concurrent.Threadの裏側 http://www.infoq.com/jp/articles/js_multithread_2
  • 22. Trampolining now = Date.now or () -> +new Date isFunction = (fn) -> typeof fn is‘function’ # 簡単な実装例 trampoline = (fn, ms) -> timeLimit = now() + ms while isFunction fn and now() < timeLimit fn = fn() # 関数の結果を自身に代入 if isFunction fn # 処理が残ってる setTimeout trampoline, 0, fn, ms # node.js なら process.nextTick return Asynchronous programming and continuation-passing style in JavaScript http://www.2ality.com/2012/06/continuation-passing-style.html
  • 23. Trampolining # 利用例 countUpWith = (iterator, limit) -> i = 0 trampoline () -> main = () -> return if ++i >= limit # undefined iterator i main # 自身を返すのがポイント , Math.floor 1000 / 60 # 60fps Asynchronous programming and continuation-passing style in JavaScript http://www.2ality.com/2012/06/continuation-passing-style.html
  • 24. Sample pp.readFile = pp.map (next, name) -> fs.readFile name, next # pp.map(iterator, callback, array_or_hash) concatPrint = ppReadFile (error, result) -> console.log error or result.join‘n’ # 部分適用された関数として利用できる concatPrint [‘a.js’,‘b.js’,‘c.js’] README かテストコード見た方が早い https://github.com/VoQn/pp.js
  • 25. Sample cpsFib = (callback, n) -> pp.whilist (next, c) -> next null, c > 0 , (next, c, a, b) -> next null, c - 1, b, a + b , (error, c, a, b) -> callback error, b , [n, 1, 0] # pp.whilist(test, iterator, callback, init_array) printFib = (n) -> cpsFib (error, result) -> console.log error or result # 部分適用された関数として利用できる printFib 10 #=> 55 README かテストコード見た方が早い https://github.com/VoQn/pp.js
  • 26. Presto Processing ? pp.js の各種 Collection API と async.js の同種の API でベンチマーク ? ソースコードは github に benchmark/ ディ レクトリで見れます https://github.com/VoQn/pp.js/tree/master/benchmark
  • 27. Presto Processing ? 大きいデータを投げた時のベンチ比較 ? [1..1.0e+7] の配列に7種のイテレータ time memory GC Full 発生 x3 なし pp 0:53.67 ?260MB 1/3 (10ms程の GC が都度) 10秒以上 async 2:58.60 - 1100MB? - ロックが数回
  • 28. etc ? Q.なんで CoffeeScript で? ? A.Github Javascript StyleGuide 見てバカにしたくなったから
  • 29. JavaScript Styleguide :: Github https://github.com/styleguide/javascript
  • 30. JavaScript Styleguide :: Github https://github.com/styleguide/javascript
  • 31. JavaScript Styleguide :: Github https://github.com/styleguide/javascript
  • 33. Feature ? しかしながら npm ライブラリ等々 coffee で書かれる事も今後増えるだろ うし、そちらの方が読めるという人が 増えるのであれば選択の一つではある ? 近日中に v0.1.0 として npm に 公開する予定 (MIT License) ? ブラウザ向け、 min.js も機能別に分 割して提供できるようにする
  • 34. Thank you ? fork, pull request, issue, code review ぜひお願いします ? macchiato も停滞気味なので 叱咤激励お願いします https://github.com/VoQn/pp.js