Permalink
Browse files

Update README.md

  • Loading branch information...
c-bata committed Mar 22, 2017
1 parent b5231f6 commit 7f329186c6c65be8b9eecbdc4762c9c84daf4d93
View
@@ -1,4 +1,4 @@
# 非同期プログラミング
# 並行処理 in Python
- Author: [Masashi Shibata (@c_bata_)](https://twitter.com/c_bata_)
- Date: 2017/03/21 (Tue)
@@ -102,7 +102,6 @@ sys 0m0.037s
![multi-thread](./img/multi-thread.png)
それではマルチスレッドを用いて、高速化してみましょう。
いくつかの危険性をもつ実装ですが、素直に書くとこのように書いてしまうかもしれません。
```python
import requests
@@ -133,8 +132,9 @@ if __name__ == '__main__':
main()
```
危険な点がいくつかありそうですが、マルチスレッドを使って並行にリクエストを送信するようにしてみました。
GILの制約があるため、Pythonにおけるマルチスレッドを行っても1つのプロセッサコアしか利用できませんが、I/O待ちなどの処理ではGILが解放されるため、その間に別のスレッドがプロセッサコアを使うことができます。
いくつか深刻な問題はありそうですが、マルチスレッドを使って並行にリクエストを送信するようにしてみました。
GILの制約があるため、Pythonにおけるマルチスレッドを行っても1つのプロセッサコアしか利用できませんが、
I/O待ちなどの処理ではGILが解放されるため、その間に別のスレッドがプロセッサコアを使うことができます。
```console
@@ -151,7 +151,6 @@ sys 0m0.028s
処理時間は1/3程度になり、非常に高速になりました。
念のため、スレッドの動きを見てみましょう。
**マルチスレッド化する前**
![同期版](./img/fetch_sync.png)
@@ -161,9 +160,9 @@ sys 0m0.028s
![マルチスレッドでのグラフ](./img/fetch_threading.png)
目標どおりの動きをしていそうです。
thrreadingモジュールを使って、高速に処理することができました。
``threading`` モジュールを使って、高速に処理することができました。
しかし、この実装は危険であるとお伝えしました
しかし、この実装には問題があるあるとお伝えしました
どうしてでしょうか?
- URLの数を増やすとどうなるでしょうか?
@@ -213,22 +212,28 @@ sys 0m0.051s
```
**1.415s** で済みました。
multithreadingモジュールを使った例よりも遅いですが、3秒かかっていたことを考えると大幅に速くなっています。
multithreadingモジュールなどは使っていませんが、何故短くなったのでしょうか?
``multithreading`` モジュールを使った例よりも少し遅いですが、3秒かかっていたことを考えると大幅に速くなっています。
``multithreading`` モジュールなどは使っていませんが、何故短くなったのでしょうか?
スレッドの動きを確認してみます。
**非同期版**
![非同期版](./img/fetch_async.png)
multithreadのときと同じようなグラフになりました。
### 多くのリクエストを送ってみる
9回ほどリクエストを送ってみます。
``multithreading`` を使った先程の実装で9回のリクエストを送るとこのようになります。
![semaphoreなしのリクエスト](./img/many_requests_without_semaphore.png)
サーバのworker数は3つなので、9個中6個のリクエストは前の処理が完了するのを待ちます。
1, 2秒待つプロセスがあるでしょう。
1, 2秒待つプロセスがあるようです。これではサーバの負荷は大きくなります。
サーバを配慮して、3つずつリクエストを送りましょう。
これは少しややこしそうですが、 ``asyncio`` では、それを簡単に実装するSemaphoreというクラスが用意されています。
書き換えると次のようになります。
```python
import aiohttp
@@ -256,7 +261,7 @@ if __name__ == '__main__':
print(r)
```
実行結果はこのようになりました。
```console
$ time python client_async_with_semaphore.py
@@ -269,6 +274,9 @@ user 0m0.318s
sys 0m0.050s
```
グラフも確認してみましょう。
![Semaphoreを使ったリクエスト](./img/many_requests_with_semaphore.png)
## マルチプロセス
Binary file not shown.
Binary file not shown.

0 comments on commit 7f32918

Please sign in to comment.