8

元の投稿の更新: 同僚が私が間違っていたことを指摘しました。他の方の参考になるかもしれないので、記事の最後に説明を記載します。


Python プログラムのネットワーク パフォーマンスの制限について基本的な理解を深めようとしていますが、異常に遭遇しました。コードフラグメント

while 1:
    sock.sendto("a",target)

ホストが送信するのと同じ速さで UDP パケットをターゲット マシンに送信します。1 秒あたり 4000 パケットをわずかに超える送信レート、つまり 1 パケットあたり 250 us を測定しました。これは、python のようなインタープリター言語でも遅いようです (プログラムは 2 GHz AMD opteron、Linux、python バージョン 2.6.6 で実行されています)。私は、TCP の Python ではるかに優れたパフォーマンスを見てきました。

これをバックグラウンドで実行して top を実行すると、python が CPU の 25% しか使用していないことがわかります。これは、python が UDP パケットの送信を人為的に遅らせている可能性があることを示唆しています。

他の誰かが同様のことを経験しましたか? Python がパケット転送速度を制限しているかどうか、またこれをオフにする方法があるかどうかは誰にもわかりませんか?

ところで、同様の C++ プログラムは 1 秒あたり 200,000 をはるかに超えるパケットを送信できるため、プラットフォームや OS の本質的な制限ではありません。


それで、私はばかげた初心者の間違いを犯したことがわかりました。gethostbyname を明示的に呼び出すのを怠っていました。そのため、sendto コマンドのターゲット アドレスにシンボリック名が含まれていました。これにより、パケットが送信されるたびに名前解決がトリガーされていました。これを修正した後、約 120,000 p/s の最大送信レートを測定しました。ずっといい。

4

2 に答える 2

1

他の人がベンチマークを繰り返すことができるように、より完全なコードサンプルを投稿することをお勧めします。ループの反復あたり250μs遅すぎます。Pythonの最適化に関する日々の経験に基づくと、Pythonのインタープリターのオーバーヘッドは、最新のマシンでは1μsをはるかに下回ると予想されます。言い換えると、C ++プログラムが1秒あたり200kパケットを送信している場合、Pythonは同じ速度であると予想されます。

(上記に照らして、sock.sendtoの属性ルックアップをループの外に移動するなどの通常の最適化の提案は、速度が別のソースから来ているため、ここでは適用されません。)

stracePythonが実際に何をしているかを確認するために使用するのが良い最初のステップです。GILで待機する時間が失われる可能性があるのは、シングルスレッドプログラムですか、それともマルチスレッドアプリケーションですか。通常のPythonソケットですかsock、それともより複雑なAPIの一部ですか?os.writeソケットを直接呼び出すときにも同じことが起こりますfilenoか?

于 2012-09-03T18:29:36.417 に答える
1

connect()最初に を実行してから、代わりに を使用してみsend()ましたsendto()か? (UDPconnect()は宛先アドレスを確立するだけで、実際には「接続」を確立しません。)私はこれに慣れていませんが、PythonはCソケットよりもアドレスパラメーターをより多く解釈すると思います。これにより、オーバーヘッドが追加される可能性があります。

于 2012-09-03T19:19:48.113 に答える