Eventletとgeventのパフォーマンスに大きな違いは何ですか?
-
12-12-2019 - |
質問
これらの2つのライブラリは、結果として同様の哲学と同様の設計上の決定を共有しています。しかし、 この人気のあるWSGIベンチマーク 言っています eventlet
よりも遅くなります gevent
.彼らのパフォーマンスは何が違うのですか?
私が知っているように、それらの主な違いは次のとおりです:
gevent
意図的に依存し、に結合されていますlibev
(libevent
, 、以前は)一方、eventlet
独立したreactorインタフェースを定義し、特定のアダプタを使用して実装しますselect
,epoll
, 、そしてその後ろにねじれた反応器。 追加のリアクターインタフェースは重要なパフォーマンスヒットを作りますか?gevent
主にCythonで書かれていますがeventlet
純粋なPythonで書かれています。 ネイティブにコンパイルされたCythonは、それほど計算的ではないがIOにバインドされたプログラムのために、純粋なPythonよりも高速ですか?のプリミティブ
gevent
標準ライブラリのインターフェイスをエミュレートしながらeventlet
'sのプリミティブは標準とは異なり、それをエミュレートするための追加の層を提供します。 追加のエミュレーション層が作るのですかeventlet
遅い?の実装です
eventlet.wsgi
ちょうどより悪いgevent.pywsgi
?
彼らは全体的に私のためにとても似ているので、私は本当に疑問に思います。
解決
まあ、geventはCythonで「ほとんど」書かれていませんが、いくつかの重要なセクションはあります。
Cythonは大きな違いを生み出します。プロセッサの最適化は、コンパイルされたコードではるかに優れています。たとえば、vmベースのシステムでは、VM実行レベルでの分岐の間接参照が不透明であるため、分岐予測はバラバラになります。キャッシュフットプリントはより厳しくなります。コンパイルされたコードはここで大きな違いをもたらし、IOはレイテンシに非常に敏感です。
同様の静脈では、libevは非常に高速です。同じ理由。
Eventletがselect hubを使用していたはずではないようです(Python2.6は通常デフォルトでepoll)。しかし、それが選択に固執していた場合、それはそれを作るでしょう 本当に 遅い(Pythonはselect fd_setをPythonリストに前後に変換する必要があるため、ループの途中にあるときは醜くなります)。
私はプロファイリングを行っていませんが、libev/libeventとCythonが大きな違いを生むことに賭けたいと思います。特に、スレッドプリミティブのいくつかはgeventのCythonにあります。多くのコードがIOやいくつかの場所で標準ライブラリを介して間接的にそれらに触れているため、これは大したことです。
Eventletの追加のエミュレーション層に関しては、より多くの弾力性があるように見えます。Geventでは、コードパスはコールバックを構築し、ハブがそれらを呼び出すように見えます。eventletは、ハブがgeventで行っている簿記の多くを実行しているようです。もう一度、しかし、私はそれをプロファイリングしていません。モンキーパッチ自体に関しては、それらはかなり似ています。
WSGIサーバーはもう1つ難しいものです。特に、geventのヘッダー解析は標準ライブラリに延期されますが、eventletではそれ自体が実装されています。これが大きな影響であるかどうかはわかりませんが、そこに何かが潜んでいても驚くことではありません。ほとんどの場合、eventletのサーバーは標準ライブラリBaseHTTPServerのmonkeypatchedバージョンに基づいています。これが非常に最適であるとは想像できません。Geventは、エミュレーションを認識するサーバーを実装します。
他のヒント
返信が遅れて申し訳ありません。
大きなパフォーマンスの違いには主に2つの理由があります。 そのベンチマークでは:
- 前に述べたように、geventのクリティカルパスは大幅に最適化されています
- そのベンチマークはストレステストを行います。マシンにできるだけ多くの要求を実行させようとするため、IOバインドされていません。そして、それがCython化されたコードが輝く場所です。
「現実の世界では」それはトラフィックの「スラッシュドット」バーストの間にのみ起こります。これは重要であり、準備ができているはずですが、それが起こると、サーバーを追加したり、リソースの重い機能を無効にしたりすることで反応します。負荷が増加したときに実際にサーバーを追加するベンチマークは見ていません。
一方、benchmarkは"通常の日"の負荷をシミュレートしますが(ウェブサイトによって異なります)、一般的にrequest、random pause、repeatに近似することができます。その一時停止が少ないほど、シミュレートしているトラフィックが多くなります。また、benchmarkのクライアント側ではレイテンシをシミュレートする必要があります。それ以外の場合は、recv/send呼び出しの前に小さな遅延を置くことによって(ベンチマークは通常より高いレベルのライブラリを使用するため、これは非
これらの条件が満たされていれば、実際にIOバインドされた問題をベンチマークします。しかし、結果はあまりにも素晴らしいではないだろう:すべての候補者は正常に10、50、さらには200qpsの負荷を提供しました。退屈な、右?そのため、待ち時間の分布、99%のリクエストに応答する時間などを測定できます。Geventはまだより良い結果を示すでしょう。しかし、その違いはほとんど印象的ではありません。