13. B O B B Y F I S C H E R P L AY I N G 5 0 O P P O N E N T S S I M U LTA N E O U S LY, 1 9 6 4
S Y N C H R O N O U S C H E S S
E X H I B I T I O N
- 50 opponents
- Fischer move in 5 seconds
- Opponents move in 55 seconds
- Game average 30 move pairs
Assumptions:
Each game runs for 30 minutes
50 sequential games would take
50 x 30 min = 1500 min = 25 hours
14. B O B B Y F I S C H E R P L AY I N G 5 0 O P P O N E N T S S I M U LTA N E O U S LY, 1 9 6 4
A S Y N C H R O N O U S C H E S S
E X H I B I T I O N
- Fischer moves on first game
- While opponent thinks, he moves
on second game, the third, fourth…
- A move on all 50 game takes him
50 x 5 sec = 250 sec = 4 min
- After he complete the round, the
first game is ready for his next move
- 50 games are completed in
4 min x 30 = 120 min = 2 hour
16. – W I K I P E D I A
C o r o u t i n e s a r e c o m p u t e r p r o g r a m
components that generalize subroutines for
nonpreemptive multitasking, by allowing
multiple entry points for suspending and
resuming execution at certain locations.
21. S I M P L E G E N E R AT O R
P Y T H O N 2 . 2 ( P E P 2 5 5 ) - 1 8 M AY 2 0 0 1
Generator was born with
“yield” expression make us
able to generate iterator
without holding memory
upfront, all you need is
memory for the current value
def eager_range(up_to):
sequence = []
index = 0
while index < up_to:
sequence.append(index)
Index += 1
return sequence
22. S I M P L E G E N E R AT O R
P Y T H O N 2 . 2 ( P E P 2 5 5 ) - 1 8 M AY 2 0 0 1
Generator was born with
“yield” expression make us
able to generate iterator
without holding memory
upfront, all you need is
memory for the current value
def lazy_range(up_to):
index = 0
while index < up_to:
yield index
Index += 1
23. C O R O U T I N E S V I A
E N H A N C E D G E N E R AT O R S
P Y T H O N 2 . 5 ( P E P 3 4 2 ) - 1 0 M AY 2 0 0 5
“send()” method on
generator, that allowed us
not only pause the
generator, but also send
back the value to generator
def jumping_range(up_to):
index = 0
while index < up_to:
jump = yield index
if jump is None:
jump = 1
index += jump
if __name__ == '__main__':
iterator = jumping_range(5)
print(next(iterator)) # 0
print(iterator.send(2)) # 2
print(next(iterator)) # 3
24. S Y N TA X F O R D E L E G AT I N G T O
A S U B G E N E R AT O R
P Y T H O N 3 . 3 ( P E P 3 8 0 ) - 1 3 F E B 2 0 0 9
“yield from” expression for yield every
value from iterator (generator) also able to
chain generator together which made us
able to bubble up and down the call stack
without code having to do anything special
def lazy_range(up_to):
index = 0
def gratuitous_refactor():
nonlocal index
while index < up_to:
yield index
index += 1
yield from gratuitous_refactor()
25. S Y N TA X F O R D E L E G AT I N G T O
A S U B G E N E R AT O R
P Y T H O N 3 . 3 ( P E P 3 8 0 ) - 1 3 F E B 2 0 0 9
“yield from” expression for yield every
value from iterator (generator) also able to
chain generator together which made us
able to bubble up and down the call stack
without code having to do anything special
def bottom():
return (yield 42)
def middle():
return (yield from bottom())
def top():
return (yield from middle())
gen = top()
value = next(gen)
print(value) # 42
26. P Y T H O N 3 . 4 ( P E P 3 1 5 6 ) - 1 2 D E C 2 0 1 2
Pluggable event loop made non blocking
IO happen, but not actual asynchronous
programming. It’s concurrent programming
A S Y N C I O
import asyncio
loop = asyncio.get_event_loop()
@asyncio.coroutine
def hello():
print('Hello')
yield from asyncio.sleep(3)
print('World!')
if __name__ == '__main__':
loop.run_until_complete(hello())
27. A S Y N C A WA I T
P Y T H O N 3 . 5 ( P E P 4 9 2 ) - 9 A P R 2 0 1 5
Explicit asynchronous code there is
no need to do “asyncio.coroutine”
decorator with generator that return
“yield from” anymore. Using
“async def” syntax to define that
function is a coroutine and use
“await” or “return” for delegate
the results like “yield from”
import asyncio
loop = asyncio.get_event_loop()
async def hello():
print('Hello')
await asyncio.sleep(3)
print('World!')
if __name__ == '__main__':
loop.run_until_complete(hello())
28. import asyncio
async def compute(x, y):
print(“Compute %s + %s …” % (x, y))
await asyncio.sleep(1.0)
return x + y
async def print_sum(x, y):
result = await compute(x, y)
print(“%s + %s = %s” % (x, y, result))
loop = asyncio.get_event_loop()
loop.run_until_complete(print_sum(1, 2))
loop.close()
A S Y N C A WA I T
P Y T H O N 3 . 5 ( P E P 4 9 2 ) - 9 A P R 2 0 1 5
Explicit asynchronous code there is
no need to do “asyncio.coroutine”
decorator with generator that return
“yield from” anymore. Using
“async def” syntax to define that
function is a coroutine and use
“await” or “return” for delegate
the results like “yield from”
30. A S Y N C G E N E R AT O R
P Y T H O N 3 . 6 ( P E P 5 2 5 ) - 2 8 J U L 2 0 1 6
Remove restriction to use await and yield
in the same function body
import asyncio
loop = asyncio.get_event_loop()
async def ticker(delay, to):
for i in range(to)
yield i
await asyncio.sleep(delay)
if __name__ == '__main__':
loop.run_until_complete(ticker(5, 10))
31. A S Y N C
C O M P R E H E N S I O N S
P Y T H O N 3 . 6 ( P E P 5 3 0 ) - 3 S E P 2 0 1 6
Introduce async for and await expression
in all kinds of comprehensions
result = [ i async for i in aiter() if i % 2 ]
result = [ await fun() for fun in funcs if await condition() ]
37. H T T P S : / / M E D I U M . F R E E C O D E C A M P. C O M / M I L L I O N - R E Q U E S T S - P E R - S E C O N D - W I T H - P Y T H O N - 9 5 C 1 3 7 A F 3 1 9
J A P R O N T O
38. J A P R O N T O
import asyncio
from japronto import Application
app = Application()
async def asynchronous(request):
for i in range(1, 4):
await asyncio.sleep(1)
print(i, ‘seconds elapsed’)
return request.Response(text=‘3 sec elapsed’)
r = app.router
r.add_route(‘/async’, asynchronous)
app.run()
47. R E F E R E N C E
- https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/
- https://hackernoon.com/asynchronous-python-45df84b82434
- https://magic.io/blog/uvloop-blazing-fast-python-networking/
- https://github.com/channelcat/sanic
- https://medium.freecodecamp.com/million-requests-per-second-with-python-95c137af319
- https://github.com/PyO3/tokio
- Miguel Grinberg Asynchronous Python for the Complete Beginner PyCon 2017
- Yury Selivanov asyncawait and asyncio in Python 3 6 and beyond PyCon 2017