2

ダウンロードする小さなファイルがたくさん (~ 1000) あります。これがマップを使用できるようにするための関数を作成しました。ダウンロード機能自体は、多くのタイムアウトを発生させた urllib2 よりも安定性を大幅に向上させるリクエストを使用します。ただし、シリアル マップを実行する場合と比較して、たとえば 4 つのプロセスで並列に実行すると、わずかに高速化されます。

data = map(get_data, IDs)
data = dview.map_sync(get_data, IDs)

私はよくわかりません:

  • map_sync は最高ですか? map_async の使用を検討しましたが、完全なリストが必要なので、違いはありませんか?
  • プロセスをスピードアップするために他に何ができますか?
  • 私の期待は、n回のダウンロードを次々に実行するのではなく、同時に並行して実行することです
4

1 に答える 1

1

ダウンロードは IO に制限されているため、実際には IPython.parallel よりも単純な ThreadPool をお勧めします (注: 私は IPython.parallel の作成者です)。始めるのははるかに簡単で、 IPython.parallel が行うことのどれも、提示されたケースに実際には役立ちません。

テスト要求にゆっくりと応答する単純なサーバーをセットアップしました。

遅いサーバーへの簡単なリクエストをテストする リクエストされ/NUMBERた数でリクエストに応答するだけですが、サーバーはリクエストの処理が人為的に遅くなります。

import requests

r = requests.get("http://localhost:8888/10")
r.content

'10'

この関数は、指定された ID の URL をダウンロードし、結果を解析しますget_data(int の str を int にキャストします)。

def get_data(ID):
    """function for getting data from our slow server"""
    r = requests.get("http://localhost:8888/%i" % ID)
    return int(r.content)

次に、さまざまな数の同時スレッドを使用して、スレッドプールを使用して一連のデータを取得することをテストします。

from multiprocessing.pool import ThreadPool

IDs = range(128)
for nthreads in [1, 2, 4, 8, 16, 32]:
    pool = ThreadPool(nthreads)
    tic = time.time()
    results = pool.map(get_data, IDs)
    toc = time.time()
    print "%3i threads: %5.1f seconds" % (nthreads, toc-tic)


  1 threads:  26.2 seconds
  2 threads:  13.3 seconds
  4 threads:   6.7 seconds
  8 threads:   3.4 seconds
 16 threads:   1.8 seconds
 32 threads:   1.1 seconds

これを使用して、ケースに適したスレッド数を把握できます。また、ThreadPool を ProcessPool に簡単に置き換えて、より良い結果が得られるかどうかを確認することもできます。

この例は IPython Notebookです。

于 2013-09-01T21:29:09.173 に答える