0

最近奇妙な問題に遭遇しました。誰かが私を助けてくれることを願っています。Ubuntu12.04 で Python2.7 を使用しています。Python と OS は両方とも 64 ビットです。

私のコードでは、受信データ ストリームをバイト配列に追加し続ける必要があります。これを実装するには、self.data += incomingdata を使用します。ここで、incomingdata はハードウェア デバイスから受信したデータです。次に、しばらくしてからバイト配列をアンパックして、受信したデータを解析します。追加操作と解析操作はすべてロックで保護されています。

ここでの問題は、"+=" を使用してバイト ストリームを追加すると、データがいくつかの時点で破損しているように見えることです (一貫して発生するわけではありません)。メモリ使用量のエラー、オーバーフローなどはありません。プログラムのメモリ使用量を監視しましたが、良さそうです。

次に、「+=」を cStringIO.write に変更して追加操作を実装すると、「+=」操作よりも遅いように見えますが、まったく問題ありません。

cStringIo.write と "+=" がバイト ストリームの操作に使用されている場合の正確な違いは何ですか? 「+=」操作は潜在的な問題を引き起こしますか?

4

1 に答える 1

1

を使用する代わりに+= 、リストを作成してその末尾にデータを追加したほうがよい場合があります。すべてのデータがフェッチされたら''.join(list)、単一の文字列を作成するために a を実行できます。文字列の連結は非効率的であるため、これははるかに優れたパフォーマンスを発揮します。

2 つの文字列を連結すると、Python は新しい文字列を格納するために新しいメモリを割り当てる必要があります。大量の連結を行っている場合、これは非常に遅くなる可能性があります。文字列のサイズが大きくなるにつれて、連結の実行にかかる時間が長くなり、この方法で大量のデータを取得すると、プロセッサが過負荷になり、他の操作が遅延する可能性があります。

TCP ストリームを再構築する Python プロセスを構築したときに、同様の問題が発生しました。キャプチャしたすべてのパケットは、連結を使用して文字列に追加していました。文字列が数 MB を超えると、私が使用していたパケット キャプチャ ライブラリがフレームをドロップし始めました。これは、CPU が文字列の連結に多くの時間を費やしていたためです。リストの使用に切り替えて、最後に結果に参加すると、問題はなくなりました。

この問題が発生しない理由はcStringIO.write、メモリ内に仮想ファイルを作成することによって動作し、毎回新しい文字列用のスペースを再割り当てすることなく、このファイルにデータを追加するためです。

于 2012-11-27T16:22:39.113 に答える