teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

11

修正

2020/08/06 22:28

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -44,7 +44,6 @@
44
44
  process_time = time.time() - start
45
45
  print(process_time)
46
46
  ```
47
- 以上です。
48
47
 
49
48
   比較として別途[aiohttpをrequestsに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
50
49
 

10

修正

2020/08/06 22:28

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -9,7 +9,7 @@
9
9
  async def download(url, session):
10
10
  print("download start")
11
11
  s = await session.get(url)
12
- await asyncio.sleep(0)
12
+ # await asyncio.sleep(0) # この行はrequestsバージョンでは必要
13
13
  sentence = await s.text() # requestsでは.textだが、aiohtttpは.text()
14
14
  print(f"download {url} completed!")
15
15
  return sentence

9

修正

2020/08/06 17:43

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -10,7 +10,7 @@
10
10
  print("download start")
11
11
  s = await session.get(url)
12
12
  await asyncio.sleep(0)
13
- sentence = await s.text()
13
+ sentence = await s.text() # requestsでは.textだが、aiohtttpは.text()
14
14
  print(f"download {url} completed!")
15
15
  return sentence
16
16
 

8

修正

2020/08/06 17:24

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -45,18 +45,27 @@
45
45
  print(process_time)
46
46
  ```
47
47
  以上です。
48
- 比較として別途[aiohttpをrequestsに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
49
- ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用している上記のコードの方が早く完了すると思います。(requestsの方はダウンロードごとにブロックされており並行処理になっていないため時間がかかる)
50
48
 
49
+  比較として別途[aiohttpをrequestsに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
51
50
 
51
+  ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用している上記のコードの方が早く完了すると思います。(requestsの方はダウンロードごとにブロックされており並行処理になっていないため時間がかかる)
52
52
 
53
+
54
+
53
55
  [補足1]
54
- 上記では、ダウンロードの並行性だけを見るため、 async def text_preprocess(sentence):内のsleepをコメント化しています。
56
+  上記では、ダウンロードの並行性だけを見るため、 async def text_preprocess(sentence):内のsleepをコメント化しています。
57
+
55
- text_preprocess処理の並行性も見る場合は、async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行してみてください。
58
+  text_preprocess処理の並行性も見る場合は、async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行してみてください。
59
+  
56
60
  3つのランダムスリープ時間の「合計」ではなく、3つのうちの最大時間までしかウェイトされないことがわかると思います。
57
61
 
58
- ただし、text_preprocess内のasyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
62
+  ただし、text_preprocess内のasyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
59
- ネットワーク通信やデータベース処理、ファイル処理等のI/Oバウンドではなく、たとえばBeautifulSoupによるタグ検索等単純にCPUの計算負荷がかかるような処理については、multiprocessを使った方がいいです。
60
63
 
64
+ ネットワーク通信やデータベース処理、ファイル処理等のI/Oバウンドではなく、たとえばBeautifulSoupによるタグ検索等単純にCPUの計算負荷がかかるような処理については、multiprocessを使った方が効果が出ると思います。
65
+
61
66
  [補足2]
62
- requestsとrun_in_executorを使う方法もありますが、イベントループやマルチスレッド寄りの話になるので割愛しました。
67
+ requestsとrun_in_executorを使う方法もありますが、イベントループやマルチスレッド寄りの話になるので割愛しました。
68
+
69
+ 参考:
70
+ [asyncio --- 非同期 I/O](https://docs.python.org/ja/3/library/asyncio.html)
71
+ [aiohttp documentation](https://docs.aiohttp.org/en/stable/)

7

修正

2020/08/06 17:22

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -18,8 +18,8 @@
18
18
  async def text_preprocess(sentence):
19
19
  # 下記は時間がかかる処理を想定
20
20
  a = random.randint(0,6)
21
- print(f"wait for {a} sec")
21
+ print(f"processing for {a} sec")
22
- # await asyncio.sleep(a) # ダウンロード処理時間だけ見たい場合、ここはコメント
22
+ # await asyncio.sleep(a) # ダウンロード処理時間だけ見たい場合、ここはコメントにする
23
23
  return a
24
24
 
25
25
  async def download_and_preprocess(url, session):
@@ -45,17 +45,18 @@
45
45
  print(process_time)
46
46
  ```
47
47
  以上です。
48
- 比較として別途[aiohttpをrequestに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
48
+ 比較として別途[aiohttpをrequestsに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
49
49
  ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用している上記のコードの方が早く完了すると思います。(requestsの方はダウンロードごとにブロックされており並行処理になっていないため時間がかかる)
50
50
 
51
51
 
52
52
 
53
- [補足]
53
+ [補足1]
54
- なお、上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たかったからです。
54
+ 上記では、ダウンロードの並行性だけを見るため、 async def text_preprocess(sentence):内のsleepをコメント化していす。
55
+ text_preprocess処理の並行性も見る場合は、async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行してみてください。、
56
+ 3つのランダムスリープ時間の「合計」ではなく、3つのうちの最大時間までしかウェイトされないことがわかると思います。
55
57
 
56
- async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行した場合、
57
- ダウンロード時間+「3つのランダムスリープ時間の合計時間ではなく、3つのうちの最大時間」までしかウェイトされないことがわかると思います。
58
- (もちろん、asyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
58
+ ただしtext_preprocess内のasyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
59
- 処理がネットワーク通信やファイル処理等のI/OバウンドではなくCPUに計算負荷がかかるような場合は、その部分はmultiprocessを使った方がいいです。
59
+ ネットワーク通信やデータベース処理、ファイル処理等のI/Oバウンドではなく、たとえばBeautifulSoupよるタグ検索等単純にCPUの計算負荷がかかるような処理については、multiprocessを使った方がいいです。
60
60
 
61
+ [補足2]
61
- なお、run_in_executorを使う方法もあるかもしれせんが、これだとマルチスレッドの話になると思ったので割愛しました。
62
+ requestsとrun_in_executorを使う方法もあが、イベントループやマルチスレッド寄りの話になるので割愛しました。

6

修正

2020/08/06 17:17

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -45,7 +45,7 @@
45
45
  print(process_time)
46
46
  ```
47
47
  以上です。
48
- 比較として別途[aiohttpではなくrequest使った場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
48
+ 比較として別途[aiohttpをrequestに単純に置き換えた場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
49
49
  ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用している上記のコードの方が早く完了すると思います。(requestsの方はダウンロードごとにブロックされており並行処理になっていないため時間がかかる)
50
50
 
51
51
 

5

修正

2020/08/06 16:16

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -54,8 +54,7 @@
54
54
  なお、上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たかったからです。
55
55
 
56
56
  async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行した場合、
57
- ダウンロード時間+「3つのランダムスリープ時間の合計時間ではなく、3つのうちの最大時間」までしかウェイトされないことがわかると思います。(並行処理されているから)
57
+ ダウンロード時間+「3つのランダムスリープ時間の合計時間ではなく、3つのうちの最大時間」までしかウェイトされないことがわかると思います。
58
-
59
58
  (もちろん、asyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
60
59
  処理がネットワーク通信やファイル処理等のI/OバウンドではなくCPUに計算負荷がかかるような場合は、その部分はmultiprocessを使った方がいいです。)
61
60
 

4

修正

2020/08/06 15:26

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -44,13 +44,12 @@
44
44
  process_time = time.time() - start
45
45
  print(process_time)
46
46
  ```
47
+ 以上です。
48
+ 比較として別途[aiohttpではなくrequestを使った場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しましたので、これを実行した場合の時間と比べてみてください。
49
+ ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用している上記のコードの方が早く完了すると思います。(requestsの方はダウンロードごとにブロックされており並行処理になっていないため時間がかかる)
47
50
 
48
- [aiohttpではなくrequestを使った場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しました。
49
- これを実行した場合の完了まで時間と比較してみてください。
50
51
 
51
- ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用しているコードの方が早く完了することがわかると思います。
52
52
 
53
-
54
53
  [補足]
55
54
  なお、上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たかったからです。
56
55
 

3

修正

2020/08/06 15:25

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -1,5 +1,4 @@
1
- requestsモジュールを使う場合、asyncioだけで期待した動作をさせるのは困難です。
2
- 代わりに非同期通信に対応したライブラリであるaiohttpを使う方法があります。
1
+ requestsモジュールの代わりに非同期通信に対応したライブラリであるaiohttpを使う方法があります。
3
2
  ```
4
3
  import asyncio
5
4
  import time

2

修正

2020/08/06 15:17

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -49,14 +49,15 @@
49
49
  [aiohttpではなくrequestを使った場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しました。
50
50
  これを実行した場合の完了まで時間と比較してみてください。
51
51
 
52
- ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用し方が早く完了することがわかると思います。
52
+ ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用しているコードの方が早く完了することがわかると思います。
53
53
 
54
54
 
55
-
55
+ [補足]
56
56
  なお、上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たかったからです。
57
57
 
58
58
  async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行した場合、
59
- ダウンロード時間+「3つのランダムスリープ時間の最大」までしかウェイトされないことがわかると思います。
59
+ ダウンロード時間+「3つのランダムスリープ時間の合計時間ではなく、3つのうちの最大時間」までしかウェイトされないことがわかると思います。(並行処理されているから)
60
+
60
61
  (もちろん、asyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
61
62
  処理がネットワーク通信やファイル処理等のI/OバウンドではなくCPUに計算負荷がかかるような場合は、その部分はmultiprocessを使った方がいいです。)
62
63
 

1

修正・追加

2020/08/06 15:15

投稿

kotori_a
kotori_a

スコア898

answer CHANGED
@@ -46,8 +46,18 @@
46
46
  print(process_time)
47
47
  ```
48
48
 
49
+ [aiohttpではなくrequestを使った場合のコード](https://gist.github.com/taizan-hokuto/5b9075f01b6a87bc0110c88cb7eac6c0)を用意しました。
50
+ これを実行した場合の完了まで時間と比較してみてください。
51
+
52
+ ネットワーク状態にもよるかもしれませんが、おおむね、aiohttpを使用した方が早く完了することがわかると思います。
53
+
54
+
55
+
49
- 上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たからです。
56
+ なお、上記で async def text_preprocess(sentence):内のsleepをコメント化しているのは、ダウンロードの並行性だけ見たかったからです。
57
+
50
- async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトしてテストした場合でも
58
+ async def text_preprocess(sentence): 内のコメント部分行(sleep)をコメントアウトして実行した場合、
51
59
  ダウンロード時間+「3つのランダムスリープ時間の最大」までしかウェイトされないことがわかると思います。
52
60
  (もちろん、asyncio.sleep()部分を実際の処理に置き換える場合、その処理自体がノンブロッキングでなければasyncioのメリットは享受できません。
53
- 処理がネットワーク通信やファイル処理等のI/OバウンドではなくCPUに計算負荷がかかるような場合は、その部分はmultiprocessを使った方がいいです。)
61
+ 処理がネットワーク通信やファイル処理等のI/OバウンドではなくCPUに計算負荷がかかるような場合は、その部分はmultiprocessを使った方がいいです。)
62
+
63
+ なお、run_in_executorを使う方法もあるかもしれませんが、これだとマルチスレッドの話になると思ったので割愛しました。