2012-09-03 28 views
7

元の記事への更新:同僚は私が間違っていたことを指摘しました。 投稿の末尾に説明がありますので、他の人には が役に立ちます。pythonのudpレート制限?


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

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

は、ターゲットマシンにUDPパケットを、ホストが送信する速度で送信します。 1秒あたり4000パケットを超える送信レートを測定します。パケットあたりです。これは、Python (プログラムは2 GHz AMD opteron、Linux、Pythonバージョン2.6.6で動作しています)のようなインタープリター言語の場合でも、遅くなります。 私はPythonでTCPの方がはるかに優れていることが分かりました。

私はPythonが人為的に UDPパケットの送信を遅らせることができることをのpythonを示唆し、CPUの だけで25%を使用していることがわかり、これをバックグラウンドで実行し、トップ実行した場合。

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

同様のC++プログラムでは、1秒間に200,000以上のパケットを送信することができます。 これはプラットフォームやOSの本質的な制限ではありません。


私はばかげた初心者ミスをしました。私はgethostbynameを と明示的に呼ぶことを怠った。したがって、sendtoコマンドのターゲットアドレスには、記号名の が含まれていました。これは、パケットが に送信されるたびに名前解決をトリガーしていました。これを修正した後、最大送信レートを約120,000 p/s測定します。 非常に良い。

+2

さらに驚くべきことに、私は名前解決がキャッシュされると思いました。あなたは先に進み、あなたの解決策を答えとして提供する必要があります。 –

答えて

0

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

(遅さが別のソースから来ているので、上記の光では、このようなループの外にsock.sendtoの属性検索を移動するなどの通常の最適化の提案は、ここでは適用されません。)

良い最初のstraceを使って、実際にPythonが何をしているのかを確認してください。シングルスレッドのプログラムか、GILを待っている時間を失うかもしれないマルチスレッドのアプリケーションですか? sockは通常のPythonソケットですか、それとももっと精巧なAPIの一部ですか?ソケットfilenoos.writeに直接電話すると同じことが起こりますか?

1

最初にconnect()を実行してから、sendto()の代わりにsend()を使用しましたか? (UDP connect()は宛先アドレスを設定するだけで、実際には "接続"を行いません。)私はこれに錆びていますが、PythonはCソケットよりもアドレスパラメータの解釈が多く、オーバーヘッドが増えていると思います。