【Python3】requestsにthreadを使用すると非常に効果的
crawler,rest api等でrequestsにてgetを大量に投げる場合、ボトルネックになるのはI/Oバウンド。
入門Python3には以下の事が書いてる。
- スレッドはI/Oバウンド問題の解決のために使う。
- CPUバウンド問題では、プロセス、ネットワーキング、イベントを使う。
requests.get()している部分をworker threadとして切り離し、Queueにてタスクを管理するとかなり高速化できる。 計測結果とサンプルコードを記載する。
結果
requestsにて10回google検索結果を取得した結果。
タイプ | 総実行時間(sec) | response.elapsed合計値(sec) |
---|---|---|
thread | 0.6119930744171143 | 0:00:01.050656 |
non thread | 5.603970766067505 | 0:00:01.089367 |
9.3倍早く終る。素ん晴らしい!
総実行時間がresponse.elapsed合計値以下になってるのが感動する。
サンプルコード
non thread版
# non_thread.py import datetime import requests import time baseurl = "http://www.google.co.jp/search?hl=ja&q=" query_list = ['inu','neko','tori','sakana','kinoko','hebi','usagi','uma','hituzji','kabutomushi'] responses = [] start_time = time.time() for q in query_list: responses.append(requests.get(baseurl+q)) elapsed_time = time.time() - start_time print("total_time : {}".format(elapsed_time)) requests_time = datetime.timedelta() for r in responses: requests_time += r.elapsed print("requests_time : {}".format(requests_time))
thread版
# thread.py import datetime import queue import threading import requests import time def query_worker(query_queue): query = query_queue.get() responses.append(requests.get(baseurl + q)) query_queue.task_done() baseurl = "http://www.google.co.jp/search?hl=ja&q=" query_list = ['inu','neko','tori','sakana','kinoko','hebi','usagi','uma','hituzji','kabutomushi'] responses = [] # queueを設定 query_queue = queue.Queue() for q in query_list: query_queue.put(q) start_time = time.time() # Thread start while not query_queue.empty(): w_thread = threading.Thread(target=query_worker, args=(query_queue,)) w_thread.start() # wait all thread are ended. query_queue.join() # total running time elapsed_time = time.time() - start_time print("total_time : {}".format(elapsed_time)) # http response total time requests_time = datetime.timedelta() for r in responses: requests_time += r.elapsed print("requests_time : {}".format(requests_time))
参考
- 作者: Bill Lubanovic,斎藤康毅,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
この本読みすぎてボロボロになってきた。
その他
PythonはGIL(グローバルインタープリタロック)が効いているのでCPUバウンド問題に対応するのにスレッド化は適さないので注意。逆に遅くなるよ!
あとはcrowlerを高速化しすぎてサーバーに怒られないように注意。
終わりに
高速化成功すると。気分いいですね。
並行処理、並列処理技術はめちゃめちゃ奥が深いので、まずは浅瀬で水浴びする程度から使っていきたい。
(おわり)