13

ローカル マシン (Mac) で Python (IPython & Canopy) と RESTful コンテンツ API を使用しています。

API からデータを取得するための 3000 個の一意の ID の配列があり、一度に 1 つの ID でのみ API を呼び出すことができます。

速度を上げるために、1000回の呼び出しを3セット並行して行うことを何とか望んでいました。

これを行う最善の方法は何ですか?

助けてくれてありがとう!

4

1 に答える 1

33

具体的に何をしているのかについての詳細な情報がなければ、確実に言うのは難しいですが、単純なスレッド化されたアプローチは理にかなっているかもしれません.

単一の ID を処理する単純な関数があるとします。

import requests

url_t = "http://localhost:8000/records/%i"

def process_id(id):
    """process a single ID"""
    # fetch the data
    r = requests.get(url_t % id)
    # parse the JSON reply
    data = r.json()
    # and update some data with PUT
    requests.put(url_t % id, data=data)
    return data

これを、一連の ID を処理する単純な関数に拡張できます。

def process_range(id_range, store=None):
    """process a number of ids, storing the results in a dict"""
    if store is None:
        store = {}
    for id in id_range:
        store[id] = process_id(id)
    return store

そして最後に、部分範囲をスレッドにかなり簡単にマップして、いくつかのリクエストを同時に実行できるようにすることができます。

from threading import Thread

def threaded_process_range(nthreads, id_range):
    """process the id range in a specified number of threads"""
    store = {}
    threads = []
    # create the threads
    for i in range(nthreads):
        ids = id_range[i::nthreads]
        t = Thread(target=process_range, args=(ids,store))
        threads.append(t)

    # start the threads
    [ t.start() for t in threads ]
    # wait for the threads to finish
    [ t.join() for t in threads ]
    return store

IPython Notebook の完全な例: http://nbviewer.ipython.org/5732094

個々のタスクにかかる時間がより広範囲に及ぶ場合は、一度に1 つずつジョブを割り当てるThreadPoolを使用することをお勧めします (個々のタスクが非常に小さい場合は遅くなることがよくありますが、異種の場合はより良いバランスが保証されます)。

于 2013-06-07T20:24:15.483 に答える