2013-06-20 2 views
6

今日、私はthis answer.という質問に応答しました。投稿した例では、bcryptノードモジュールで同期バージョンの呼び出しを使用しました。私は主に同期のバージョンを使用することを選択しました。なぜなら、応答が少しきれいに見えると思ったからです。しかし、bcryptはI/Oバウンドの代わりにCPUとメモリを消費するため、性能に影響するとは考えていませんでした。ブラウザがそうであるように、ノードがほとんどすべてのコードを1つのスレッドで実行し、I/Oやデータベースアクセスなどのためにバックグラウンドスレッドしか使用していなかったことは私の理解であった。これにより、CPU負荷の高いタスクは本質的にサーバーを「ブロックする」と考えられました。なぜなら、作業負荷を軽減する他のスレッドがないからです。node.jsの非同期プログラミングはCPUバインドされたタスクを高速化しますか?

私の回答に対するコメントは、私の前提が間違っていることを示し、いくつかの研究の後で、node.jsがこのようなことをどのように処理するかを本当によく理解していないことに気付きました。 node.jsの非同期プログラミングは、CPUとメモリを必要とする呼び出しを高速化しますか?もしそうなら、それはどうしますか?

+0

"node.jsの非同期プログラミングは、CPUとメモリを消費するコールを高速化しますか?" ---それはそうするふりをします。砂時計のように、あなたがそれらを見ているときにOSをスピードアップします。 – zerkms

答えて

7

モジュールの実装方法によって異なります。

モジュールがスレッディングをサポートせずに実装されている場合は、CPUバインド処理を非同期で行うことはできません。いくつかの関数はコールバックと私の外見を非同期で提供しますが、実際はそうではありません。実際には同期して実行され、イベントループをブロックします。この例のjavascriptはArray.forEach()です。

しかし、バックグラウンドスレッドでの処理を行うためにモジュールを実装することができます。この場合、それは本当に非同期であり、CPUに束縛されたタスクをスピードアップすることができます。少なくとも、バックグラウンドスレッドがビジー状態のコンピューティング結果を受け取っている間は、イベントループを解放して着信要求を処理します。

この例は、ノード独自の暗号モジュールのcrypto.pbkdf2()機能です。

しかし、node.jsが1つのスレッドで実行されている場合、モジュールは他のスレッドでどのようにコードを実行できますか?

これが実装された元の方法は、単にモジュールがjavascriptで書かれていたのではなく、代わりにC/C++で書かれ、addons APIを介してnode.jsにインターフェイスされているということでした。

しかし最近では、純粋なjavascriptモジュールや関数でもスレッドやプロセスが生成される可能性があります。ノードにはノードプロセスのマスタ/スレーブクラスタを設定するClusterという実験的なモジュールがあります。モジュールまたはコードは、ワーカープロセスでCPUバインドタスクを実行し、メインノードプロセスを解放してイベントループを処理します。 npmにはいくつかのスレッドモジュールもあります。 npmjs.orgで「スレッド」を検索するだけです。

したがって、CPUバインドされたタスクを高速に実行するか、少なくとも非同期で実行することでメインイベントループをブロックしないようにすることができます。

+1

偉大な答え。ソースコードを調べたところ、私が推薦したbcryptモジュールは実際にはC/C++コードを使って計算を行い、非同期呼び出しによって高速化されることが判明しました。私はオリジナルの答えのコメント作成者が正しいと思うし、非同期呼び出しをデフォルトで使い、必要があると知って同期呼び出しを選択する方が良いでしょう。 – TwentyMiles

関連する問題