2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Play Python async

Last updated at Posted at 2015-08-29

There are a few post about python asyncio introduced since Python 3.3. I played around and this is the note for myself.

Summary

I evaluated thread and coroutine and find out the fact that the performace does not have a huge difference. Though, async is faster a little.(delimiter: I tested them with a really simple model. I do not say this is the ground truth.) Perhaps, the advantage of coroutine is chaining using yield from, which is easy to write compared with using queue and thread

Spec

  • Python 3.5dev
  • Mac OSX 10.10
  • Memory DDR3 16GB
  • CPU 2.3 GHz Intel Core i7

Python async module was introduced in 3.3.

I'm not trying to reinvent the wheel. I'm trying to build a good one.

Guido van Rossum

import asyncio

  • Reference implementation for PEP-3156.
  • Basic components for doing async i/o
  • Works officially on Python >= 3.3

Goals

  • Modern implementation of async i/o for Python
  • Use yield from (PEP-380)
  • Don't use anything that requires Python > 3.3
  • Interoperabililty with other frameworks
  • Unix and Windows support
  • IPv4 and IPv6
  • TCP, UCP and pipes
  • Basic SSL
  • Subporcess

Non goals

  • Perfection
  • Replacing current framwork
  • Protocol implementations
  • Replace http, smtplib, ...
  • Make it work on Python < 3.3

Coroutine, Futures and Tasks

Coroutines

  • generator function, can receive values
  • decorated with @coroutine
    Future
  • promise of a result or an error
    Task
  • Future which runs a coroutine

Thread vs Coroutine

import time
import asyncio
import threading
import numpy as np


def fib(n):
    if n in (1, 2):
        return 1
    return fib(n - 1) + fib(n - 2)

@asyncio.coroutine
def co_fib(n):
    if n in (1, 2):
        return 1
    return fib(n - 1) + fib(n - 2)

def coroutine_test(n):
    tasks = [asyncio.ensure_future(co_fib(20)) for _ in range(n)]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))

def thread_test(n):
    threads = [threading.Thread(target=fib, args=(20,)) for _ in range(n)]
    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

def evaluate(n, m):
    r = []
    print("thread start")
    for _ in range(n):
        s = time.time()
        thread_test(m)
        process_time = time.time() - s
        r.append(process_time)
    print("thread average: ", np.average(r), " secs")
    print("thread distribution: ", np.var(r))

    r = []
    print("coroutine start")
    for _ in range(n):
        s = time.time()
        coroutine_test(m)
        process_time = time.time() - s
        r.append(process_time)
    print("coroutine average: ", np.average(r), " secs")
    print("coroutine distribution: ", np.var(r))


if __name__ == "__main__":
    evaluate(100, 1000)


Result

thread start
thread average:  2.26430218458  secs
thread distribution:  0.000516381104439
coroutine start
coroutine average:  2.17451543093  secs
coroutine distribution:  0.00377455202351

reference

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?