概要
UI の動きやユーザの操作を妨げないためには処理を非同期に行う必要があります.特に CPU 負荷が大きい処理は別のコアで処理させるために別スレッドでやらせます.しかし JavaScript はマルチスレッドで動かないため,こういったユースケースでは別プロセスに重い処理を任せます.
この時,ほぼ必要になるのがプロセス間通信(IPC)です.Electron アプリでは基本的に2種類の IPC が使えます.
- Electron アプリではほとんどがレンダラプロセスで処理される.なので手の空いているメインプロセスを使って,Electron の IPC API で通信する.
- レンダラプロセスから
child_process.fork()
で新しいプロセスを起こし,send()
や'message'
イベントで通信する Node.js の IPC
どちらのほうが良いのかを知りたかったので試してみました.
今回のコードは全て下記のリポジトリにあるので,ここには必要な情報だけ書きます.
テスト環境
- OS X
- MacBook Pro 2015 Mid
- CPU: 2.7 GHz Intel Core i5
- Memory: 8 GB 1867 MHz DDR3
- Node.js 5.10.1
- Electron 0.37.4
テスト内容
- 大きめのオブジェクト 送信側から受信側に1ツイート分のオブジェクトを98回順番に送信し,1回の送信とその ACK にかかった時間を調べます
- 小さめのオブジェクト 送信側から受信側に整数1つを98回順番に送信し,1回の送信とその ACK にかかった時間を調べます
それぞれを Node.js と Electron それぞれの API で10回ずつ行います.
結果
送信にかかった平均時間と,データをざっと見た感じかかる時間の振れ幅が結構大きかったので分散も出しました.
平均時間 [ns]
Node.js | Electron | |
---|---|---|
Large | 938029.1246169561 | 779345.2921348314 |
Small | 832760.226762002 | 406117.63636363635 |
分散 [ns^2]
Node.js | Electron | |
---|---|---|
Large | 45081610954226 | 110908047760 |
Small | 43818214306282 | 72026021464 |
比較するとツイート1つ分程度までなら Electron の IPC のほうが優秀です.また,小さいデータ(整数1つ分)については Electron のほうが倍近い速いです.
ただ,Electron の IPC は送信サイズが大きくなると性能が悪化するとのことなので,これよりさらに大きいオブジェクトになると逆転するかもしれません.
また,この程度の差なら別の要素で決めてしまって良いかもしれません(すでにメインプロセスが動いてるからそっちを使いたいや,2つ以上動かして死活管理したいから Node.js IPC 使いたい,そもそもレンダラプロセスを fork するのはメモリ使用量とか的にどうなのなど).ヘビーに使う人でなければそんなに気にする必要は無さそうです.