質問: " + state.x + ", y= " + state.y + ", z= " + state.z); }) .catch(e => { console.log(e); }); } function getValuesForZ() { return state => Object.assign(state, {z:['value1', 'value2'].concat(state.x)}); } function processItem() { return item => 'processed:' + item; } function processY() { return state => { return Promise.resolve(state.y) .then(processYnest()) .then(y => Object.assign(state,{y})); }; } function processYnest() { return y => 'processed in nested function:' + y; } main() ``` 普通版は 34行に対して、Promise 版は48行と行数は増えてしまいましたが、処理順にプログラムを書くことができて、かつ、サブルーチンによるモジュール化もできていると思います。 モジュール化のみそは、サブルーチンが演算結果を返すのではなく、演算を行う関数を返すことです。このようにすることで、呼び出し側は非同期にその関数を呼び出すことができるわけです。 プログラムの詳細な説明は避けますが、順次処理、条件判定、繰り返し処理、サブルーチンのネスト呼び出しを含める例となっています。プログラムの処理内容には何の意味もありません。また、両方を比較しやすいように非同期処理は入っていませんが、Promise版の方ではいくらでも非同期処理を挿入できますが、普通版では非同期処理を挿入することは不可能です。 ※1の参考: TCP/IP - Solving the C10K with the thread per client approach 「サーバ書くなら epoll 使うべき」は、今でも正しいのか いずれも、協調的マルチタスクに比べれば性能は出ないと思いますが、「協調的マルチタスクがないと1万コネクションはできないのかというとそうではない」という主張だと思います。桁が上がって10万コネクションになれば、やはり協調的マルチタスクが必要なのかもしれません。
回答: > > 質問:どっちが好きですか・どっちが勝つと思いますか > > > 一旦個人の好き嫌いは脇におきます。 マルチスレッド/非協調的なプリエンティブ並行処理モデル と イベント駆動/協調的なノン・プリエンティブ並行処理モデル は勝ち負けではなく、両者を**組み合わせ**て利用すべきものと考えます。また、一般論としてはマルチスレッド・モデルの方が、イベント駆動に比べてプログラミングが簡単になるはずです(私の経験則とも合致します)。 > > 私は個人的にはイベント駆動型が好きで、性能問題でマルチスレッド派を駆逐して欲しいくらいに思っています。 > > > 性能問題にフォーカスした場合、(あなたの言うイベント駆動型=シングルスレッド・モデルであれば、)イベント駆動型はプロセッサのマルチコア化に追従できません。イベント駆動でもマルチプロセス・アプリケーションであればスケーラビリティを得られますが、そもそもマルチプロセスは非協調並行処理ですからマルチスレッドと組み合わせるのと同じことです。結局のところ、マルチプロセス化はイベント駆動と非協調処理を組み合わせているにすぎません。 > > JavaScript のコールバックは嫌いですか?lua などコルーチンの yield って懐かしくないですか? > > > 上記の追加質問と、それまでの論点との関連性がイマイチ不明瞭ですが... 改訂後の質問内容へのコメント: > > OSレベルでは多重入力はイベント駆動で実装されているわけで、そのイベント駆動をそのままコーディングできるシングルスレッドイベント駆動プログラミングって気持ち良くないですか? > > > JavaScript/Node.jsのように綺麗なイベント駆動モデルなら(それなりに)賛同できますが、OSレベルにより近いselectやepollによるイベント駆動処理は、とにかく面倒でプログラミングも苦痛です。このあたりはlibuv (Node.jsも同ライブラリ利用)のようなイベント駆動フレームワークが、低レイヤにおける暗部を覆い隠している恩恵と思います。 一方でマルチスレッドモデルとして挙げている例は、「微妙なタイミング判定」で確かに排他制御が必要なものの、本質的には「いつ割込判定を行うか」という点のみを問題視しているように見えました。イベント駆動フレームワークは、この判定タイミングを「イベントループ」という形で標準化しただけとも言えます。 そういう意味では、マルチスレッドで性能と柔軟性を優先する(設計・デバッグ難易度は上がる)か、イベント駆動で標準化された構造を好む(自由度は低くマルチコア非対応)かという話なのかもしれません。 > > マルチスレッドプログラミングって難しくないですか? > > > はい。非同期プログラミングは **本質的に** 難解です。これはイベント駆動モデルであっても、複数I/Oを制御するような非同期処理メインでは似たような難しさがあると思います。イベント駆動をマルチスレッド処理と比べたときの利点は、非決定的要因(≒タイミングに依存した処理結果)が比較的少ないという点でしょうか。