ここで「間違ったことをしている」のではないかと心配です。特に、一部の人々が作成したきちんとした小さな注釈をどのように作成するかはわかりません。しかし、私はこのスレッドで行う多くの懸念/観察があります。
1)人気のある回答の1つにある疑似コードのコメント要素
result = query( "select smurfs from some_mushroom" );
// twiddle fingers
go_do_something_with_result( result );
本質的に偽物です。スレッドが計算している場合、それは親指をいじるのではなく、必要な作業を行っています。一方、単にIOの完了を待機しているだけで、CPU時間を使用していない場合、カーネル内のスレッド制御インフラストラクチャの要点は、CPUが何か便利なことを見つけるということです。ここで提案されている「親指をいじる」唯一の方法は、ポーリングループを作成することです。実際のWebサーバーをコーディングした人は、それを行うのに十分な能力を備えていません。
2)「スレッドは難しい」。データ共有のコンテキストでのみ意味があります。独立したWebリクエストを処理する場合のように、本質的に独立したスレッドがある場合、スレッド化は非常に簡単です。1つのジョブを処理する方法の線形フローをコード化し、複数のリクエストを処理することを理解し、実質的に独立しています。個人的には、ほとんどのプログラマーにとって、クロージャー/コールバックのメカニズムを学ぶことは、単に上から下へのスレッドバージョンをコーディングするよりも複雑であることを知っています。(ただし、スレッド間で通信する必要がある場合、人生は本当に非常に速くなりますが、クロージャー/コールバックのメカニズムが実際にそれを変更するとは確信していません。このアプローチはまだスレッドで実現可能であるため、オプションを制限するだけです。とにかく、それは
3)これまでのところ、特定のタイプのコンテキストスイッチが他のタイプのコンテキストスイッチよりも時間がかかる理由について、誰も実際の証拠を提示していません。マルチタスクカーネル(組み込みコントローラーの小規模なもので、「実際の」OSほど豪華ではない)を作成した経験から、これは当てはまらないことが示唆されています。
4)私がこれまでに見た、他のウェブサーバーよりもノードがどれだけ速いかを示すことを意図しているすべてのイラストには、ひどい欠陥がありますが、ノードに確実に受け入れられる1つの利点を間接的に示す方法で欠陥があります(そしてそれは決して重要ではありません)。ノードは、チューニングが必要な(実際には許可さえされていない)ように見えません。スレッドモデルがある場合は、予想される負荷を処理するのに十分なスレッドを作成する必要があります。これをひどく行うと、パフォーマンスが低下します。スレッドが少なすぎる場合、CPUはアイドル状態ですが、追加の要求を受け入れることができず、作成するスレッドが多すぎるため、カーネルメモリが浪費され、Java環境の場合は、メインヒープメモリも無駄になります。 。さて、Javaにとって、ヒープの浪費は、システムのパフォーマンスを台無しにする最初の、最良の方法です。効率的なガベージコレクション(現在、これはG1で変更される可能性がありますが、陪審は少なくとも2013年の初めの時点ではまだその点で出ていないようです)は、多くの予備ヒープがあるかどうかに依存するためです。したがって、問題があります。スレッドが少なすぎるとチューニングが行われ、CPUがアイドル状態になりスループットが低下し、多すぎるとチューニングが失敗し、他の点で問題が発生します。
5)Nodeのアプローチは「設計上、より高速である」という主張の論理を受け入れる別の方法があります。それがこれです。ほとんどのスレッドモデルは、タイムスライスされたコンテキストスイッチモデルを使用し、より適切な(値判断アラート:)およびより効率的な(値判断ではない)プリエンプティブモデルの上に階層化されます。これは2つの理由で発生します。1つ目は、ほとんどのプログラマーが優先プリエンプションを理解していないように見えることです。 ;特に、Javaの最初のバージョンでは、Solaris実装で優先度の優先使用とWindowsでのタイムスライスが使用されていました。ほとんどのプログラマーは、「Solarisではスレッドが機能しない」ことを理解していないため、彼らはモデルをどこでもタイムスライスに変更しました)。とにかく、要点は、タイムスライシングが追加の(そして潜在的に不要な)コンテキストスイッチを作成することです。すべてのコンテキストスイッチはCPU時間を消費し、その時間は実際の手元のジョブで実行できる作業から効果的に削除されます。ただし、かなり奇妙なことが起こっている場合を除いて、タイムスライシングのためにコンテキストの切り替えに費やされる時間は、全体の時間のごくわずかな割合を超えてはなりません。シンプルなウェブサーバー)。したがって、はい、タイムスライシングに伴う過剰なコンテキストスイッチは非効率的です(そして、これらは その時間は、手元にある実際の作業で実行できる作業から効果的に取り除かれます。ただし、かなり奇妙なことが起こっている場合を除いて、タイムスライシングのためにコンテキストの切り替えに費やされる時間は、全体の時間のごくわずかな割合を超えてはなりません。シンプルなウェブサーバー)。したがって、はい、タイムスライシングに伴う過剰なコンテキストスイッチは非効率的です(そして、これらは その時間は、手元にある実際の作業で実行できる作業から効果的に取り除かれます。ただし、かなり奇妙なことが起こっている場合を除いて、タイムスライシングのためにコンテキストの切り替えに費やされる時間は、全体の時間のごくわずかな割合を超えてはなりません。シンプルなウェブサーバー)。したがって、はい、タイムスライシングに伴う過剰なコンテキストスイッチは非効率的です(そして、これらは原則としてカーネルスレッド)ですが、違いはスループットの数パーセントであり、Nodeによく含まれるパフォーマンスの主張に含まれる整数の要素ではありません。
とにかく、そのすべてが長くて乱暴なものであることをお詫びしますが、私は今のところ、議論は何も証明しておらず、これらの状況のいずれかで誰かから連絡をいただければ幸いです:
a)Nodeの方が優れている理由の実際の説明(上記で概説した2つのシナリオを超えて、その最初の(微調整)は、これまでに見たすべてのテストの実際の説明だと思います。([編集]実際、考えれば考えるほど、膨大な数のスタックで使用されるメモリがここで重要になるのではないかと考えています。最近のスレッドのデフォルトのスタックサイズはかなり大きくなる傾向がありますが、クロージャベースのイベントシステムは必要なものだけです)
b)選択したスレッド化サーバーに実際に公平な機会を与える実際のベンチマーク。少なくともその方法では、主張が本質的に偽であると信じるのをやめる必要があります;>([編集]これはおそらく私が意図したものよりも強力ですが、パフォーマンスの利点についての説明はせいぜい不完全であり、示されているベンチマークは不合理です)。
乾杯、トビー
select()
は、スレッドコンテキストスワップよりも高速です。