0

一度に多くのページをロードして解析し、それらからサーバーにデータを送信するクライアントを作成しています。一度に 1 つのページ プロセッサを実行すると、かなりうまくいきます。

********** Round-trip (with 0 sends/0 loads) for (+0/.0/-0) was total 1.98s (1.60s load html, 0.24s parse, 0.00s on queue, 0.14s to process) **********
********** Round-trip (with 0 sends/0 loads) for (+0/.0/-0) was total 1.87s (1.59s load html, 0.25s parse, 0.00s on queue, 0.03s to process) **********
********** Round-trip (with 0 sends/0 loads) for (+0/.0/-0) was total 2.79s (1.78s load html, 0.28s parse, 0.00s on queue, 0.72s to process) **********
********** Round-trip (with 0 sends/1 loads) for (+0/.0/-0) was total 2.18s (1.70s load html, 0.34s parse, 0.00s on queue, 0.15s to process) **********
********** Round-trip (with 0 sends/1 loads) for (+0/.0/-0) was total 1.91s (1.47s load html, 0.21s parse, 0.00s on queue, 0.23s to process) **********
********** Round-trip (with 0 sends/1 loads) for (+0/.0/-0) was total 1.84s (1.59s load html, 0.22s parse, 0.00s on queue, 0.03s to process) **********
********** Round-trip (with 0 sends/0 loads) for (+0/.0/-0) was total 1.90s (1.67s load html, 0.21s parse, 0.00s on queue, 0.02s to process) **********

ただし、最大 20 を一度に (それぞれ独自のスレッドで) 実行すると、HTTP トラフィックが著しく遅くなります。

********** Round-trip (with 2 sends/7 loads) for (+0/.0/-0) was total 23.37s (16.39s load html, 0.30s parse, 0.00s on queue, 6.67s to process) **********
********** Round-trip (with 2 sends/5 loads) for (+0/.0/-0) was total 20.99s (14.00s load html, 1.99s parse, 0.00s on queue, 5.00s to process) **********
********** Round-trip (with 4 sends/4 loads) for (+0/.0/-0) was total 17.89s (9.17s load html, 0.30s parse, 0.12s on queue, 8.31s to process) **********
********** Round-trip (with 3 sends/5 loads) for (+0/.0/-0) was total 26.22s (15.34s load html, 1.63s parse, 0.01s on queue, 9.24s to process) **********

bit は、処理中の Web ページ ( to ) の HTML を読み取るのload htmlにかかる時間です。ビットは、このクライアントからそれを処理するサーバーまでの往復にかかる時間です ( )。ビットは、サーバーへの同時送信数と、サーバーへの要求が行われたときに実行されていた、処理中の Web ページからの読み込み数です。resp = self.mech.open(url)resp.read(); resp.close()to processfp = urllib2.urlopen(...); fp.read(); fp.close()X sends/Y loads

ちょっと気になるのが一番to process。サーバー上での実際の処理は、ほんの少しかかります0.2s送信されるのは400 バイトだけなので、帯域幅を使いすぎても問題ありません。興味深いのは、5 つのスレッドを開き、そのビットだけを繰り返し実行するプログラムを実行すると (解析がこの同時の送信/読み込みで行われている間に)、to process非常に高速になることです。

1 took 0.04s
1 took 1.41s in total
0 took 0.03s
0 took 1.43s in total
4 took 0.33s
2 took 0.49s
2 took 0.08s
2 took 0.01s
2 took 1.74s in total
3 took 0.62s
4 took 0.40s
3 took 0.31s
4 took 0.33s
3 took 0.05s
3 took 2.18s in total
4 took 0.07s
4 took 2.22s in total

to processこのスタンドアロン プログラムの各処理時間0.01s0.50s、本格的なバージョンの 6 ~ 10 秒よりもはるかに短く、送信スレッドの使用量も少なくありません (5 を使用し、本格的なバージョンの上限は5)。

つまり、本格的なバージョンが実行されている間に、(+0/.0/-0)それぞれ 400 バイトのまったく同じ要求を送信する別のバージョンを実行すると0.31、各要求に対して s しかかかりません。したがって、私が実行しているマシンがタップされているわけではありません...むしろ、他のスレッドでの複数の同時ロードが高速であるべきものの速度を低下させているようです(実際、実行中の他のプログラムでは高速です)同じマシン) は、他のスレッドで送信します。

送信は で行われurllib2.urlopen、読み取りは mechanize (最終的には のフォークを使用urllib2.urlopen) で行われます。

本格的なプログラムを、少なくとも同じものを送信しているときに、このミニスタンドアロン バージョンと同じくらい速く実行する方法はありますか? 名前付きパイプなどを介して送信するものを受け取るだけの別のプログラムを作成して、送信が別のプロセスで行われるようにすることを考えていますが、それはどういうわけかばかげているようです。どんな提案でも大歓迎です。

これらの複数の同時ページ読み込みを高速化する方法に関する提案も歓迎します (したがって、時間は 10 ~ 20 秒ではなく 1 ~ 3 秒のように見えます)。


編集: 追加メモ: 私は機械化の Cookie 処理機能に依存しているため、どのような回答でもそれに対処する方法が理想的に提供されます...


編集: 1 つのページだけが開かれ、一度に 10 ~ 20 個のものがキューに追加される、別の構成で同じ設定をしています。それらはバターを通してナイフのように処理されます。例えば、これは束全体を追加した後の最後です:

********** Round-trip (with 4 sends/0 loads) for (+0/.0/-0) was total 1.17s (1.14s wait, 0.04s to process) **********
********** Round-trip (with 4 sends/0 loads) for (+0/.0/-0) was total 1.19s (1.16s wait, 0.03s to process) **********
********** Round-trip (with 4 sends/0 loads) for (+0/.0/-0) was total 1.26s (0.80s wait, 0.46s to process) **********
********** Round-trip (with 4 sends/0 loads) for (+0/.0/-0) was total 1.35s (0.77s wait, 0.58s to process) **********
********** Round-trip (with 4 sends/0 loads) for (+2/.4/-0) was total 1.44s (0.24s wait, 1.20s to process) **********

wait(情報が送信される前にキューに待機していた時間であるタイミングを追加しました。)to processは、スタンドアロン プログラムと同じくらい高速であることに注意してください。この問題は、Web ページの読み取りと解析を常に行っているページでのみ発生します。(解析自体が多くの CPU を消費することに注意してください)。


編集: いくつかの予備テストでは、Web ページの読み込みごとに個別のプロセスを使用する必要があることが示されています... 起動して実行されたら、更新を投稿します。

4

1 に答える 1

1

おそらくグローバル インタープリター ロック (GIL) です。代わりにマルチプロセッシング モジュールを試しましたか (ほとんどの場合、スレッド化のドロップイン代替品である IIRC)。

スレッド化により Python コードのパフォーマンスが低下するも参照してください。

于 2012-06-15T02:25:02.393 に答える