APIの実行速度を上げてみた ~非同期処理編~



●著者

がくしです。







●前回の記事


●目的

前回同様、APIを使ったプログラミングの実行速度を上げる手法を紹介します。今回は非同期処理を使います。まずはじめに非同期処理の解説をして、最後にAPIへの応用をお見せします。



●非同期処理とは

複数のタスクを実行する際に、あるタスクの処理が停止している間に別のタスクの処理を進める手法です。各タスクは、coroutineという形式で管理されます。

この説明だけでは分からないと思うので、coroutineについて説明していきます。ポイントは3つあります。


・coroutineの作り方/使い方
・coroiutineの連鎖
・coroutineの並列


それぞれ見てみましょう。



●coroutineの作り方/使い方


async

関数定義の頭にasyncを書くことで、その関数をcoroutineとすることができます(正確には、関数の実行結果がcoroutineです)。ここでは、parent関数とchild関数をcoroutineとして定義しています。


loop

この3行でcoroutineを実行できるとだけ理解してもらえれば十分です。



●coroutineの連鎖

複数のcoroutineは、awaitを通じて連鎖させることができます。もう一度コードを見てみましょう。


parentでは「await child(num)」という形で使われています。これは、「child(num)のタスクが完了するまで待ってから以降の処理を行う」という意味になります。これがcroutineの連鎖です。


childでは「await async.sleep(num)」という形で使われています。async.sleep(num)は、「num秒待機する」というタスクを課したcoroutineを返します。


実行結果は以下のようになります。childの完了後に、await以降の処理が行われている事がわかります。


$ python simple_coroutine.py
Bob start
Bob's child waiting...
Bob's child waited 3sec
Bob end



●coroutineの並列

coroutineは並列することでその真価を発揮します。もう一度、最初の説明を見てみましょう。


複数のタスクを実行する際に、あるタスクの処理が停止している間に別のタスクの処理を進める手法


これは、「coroutineを並列して実行している際に、あるcoroutineがawaitしている間に別のcoroutineの処理を進める」という意味になります。実際のコードを見てみましょう。新しくparallelという関数を追加しました。



新しくparallelという関数を追加しました。BobとAliceという2つのcoroutineを作成し、並列処理をしています。async.waitが、並列処理を管理するcoroutineとなります。実行結果を見てみましょう。


$ python parallel_coroutine.py
Alice start
Alice's child waiting...
Bob start
Bob'child waiting...
Bob's child waited 3sec
Bob end
Alice's child waited 5sec
Alice end


Aliceが開始しAlice's childが待機している間に、Bobが動いている事が分かります。これが、非同期処理です。



●非同期処理のまとめ

・タスクをcoroutineの形式で管理
・awaitでcoroutineを連鎖
・await中に別のcoroutineを処理


これらを踏まえて、APIへの応用を見てみましょう。



●コード全文



●補足

aiohttp

urlopenやrequestは非同期処理に対応していないので、aiohttpを使用。


asyncio.Queue()

非同期処理の出力を管理



●性能比較

前回と同様に、1000件の記事のlike数を取得するのに要する時間を測定しています。


・シングルスレッド(通常の処理)

・マルチスレッド(前回作ったもの)

・非同期処理(今回作ったもの)


通常の処理が2分程かかるのに対して、非同期処理だと5秒ほどで済むことが分かります。25倍以上の速度改善がなされてます。爆速ですね。


●最後に

今回は解説にも挑んでみましたが、やはり難しいものですね。ただ、コード自体は小奇麗にまとまってると思うので、せめてそこだけでも誰かのお役に立てれば幸いです。


かしこ。

公開日:2018/11/14
獲得ALIS:37.80
がくし's icon'
  • がくし
  • @gaxiiiiiiiiiiii
養蜂家。暇な時にプログラミングをして遊んでる。
コメントする
コメントする