⌛
async/awaitを使ったら遅くなった話【python】
ある日、pythonのasync/awaitを学ぼうと思い、この動画を見ながらコードを書いていました。
change_async関数の作成
そうしたら、「コルーチンに変換する関数作れば楽かも」と思い試しにコードを書いてみました。
async.py
#import
import time
import asyncio
import numpy as np
#this function can change to async function
async def change_async(func, *args, **keywords):
return func(*args, **keywords)
#async main
async def async_main():
xx = await change_async(np.arange, 0, 4)
yy = await change_async(np.arange, 0, 4)
xx, yy = np.meshgrid(xx, yy)
for xi, x in enumerate(xx):
for yi, y in enumerate(yy):
print(x[xi], y[yi])
if __name__ == "__main__":
#async_main run
start = time.time()
asyncio.run(async_main())
end = time.time()
print(f"execution speed of async_main: {end - start}")
このコードは、change_asyncという、関数をコルーチンに変換する関数を作り、np.arangeをコルーチンに変換し、awaitで並列処理しています。
その結果はこちら。
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3
execution speed of async_main: 0.004174232482910156
最初は、このコードの実行速度が遅くなっていることを知らず、成功したと思い込んでいました。
async/awaitありなしの比較
しかしその後、「これasync使わずに書いたコードよりどのくらい早いのかな」と思い、試してみました。
そのコードがこちら。
async.py
#async.py
#import
import time
import asyncio
import numpy as np
#this function can change to async function
async def change_async(func, *args, **keywords):
return func(*args, **keywords)
#async main
async def async_main():
xx = await change_async(np.arange, 0, 4)
yy = await change_async(np.arange, 0, 4)
xx, yy = np.meshgrid(xx, yy)
for xi, x in enumerate(xx):
for yi, y in enumerate(yy):
print(x[xi], y[yi])
#main
def main():
xx = np.arange(0, 4)
yy = np.arange(0, 4)
xx, yy = np.meshgrid(xx, yy)
for xi, x in enumerate(xx):
for yi, y in enumerate(yy):
print(x[xi], y[yi])
if __name__ == "__main__":
#async_main run
start = time.time()
asyncio.run(async_main())
end = time.time()
print(f"execution speed of async_main: {end - start}")
#main run
start = time.time()
main()
end = time.time()
print(f"execution speed of main: {end - start}")
このコードは、さっきのasync_main関数とasyncではないmain関数の実行速度を比較できるようになっています。
このコードを実行した時、その真実を知ってしまいましたw
その結果がこちら。
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3
execution speed of async_main: 0.004174232482910156
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3
execution speed of main: 0.002992391586303711
そう、上(async_main)より下(main)の方が実行速度が早いのです。
おわり
このことから、async/awaitは必ずしも実行速度を速くさせるわけではないことが分かりました。むしろ、場合によっては実行速度を遅くさせる可能性もあります。
async/awaitは、ちゃんと実行速度が早くなることを確認してから使いましょう。
Discussion