ch20 files

This commit is contained in:
Luciano Ramalho committed 2021-01-29 21:05:03 -03:00
1 parent 07856d4f30
commit a3bf91bc59
9 files changed
+945 -28

No files matched your search

+260
View File
@@ -0,0 +1,260 @@
1 42.05
2 22.81
3 15.95
4 13.28
5 12.27
6 10.38
7 11.00
8 11.41
9 12.17
10 12.69
11 11.34
12 11.35
13 10.88
14 11.63
15 11.79
16 11.49
17 11.29
18 10.78
19 10.92
20 11.07
1 40.47
2 22.93
3 15.88
4 13.25
5 12.22
6 10.95
7 10.81
8 11.26
9 11.96
10 12.43
11 11.19
12 10.91
13 11.03
14 10.56
15 10.62
16 11.73
17 11.00
18 12.81
19 12.38
20 11.28
1 40.81
2 22.79
3 15.83
4 13.27
5 12.33
6 10.65
7 10.94
8 11.48
9 11.78
10 12.78
11 11.31
12 10.97
13 10.80
14 10.93
15 10.69
16 10.57
17 10.54
18 10.55
19 10.79
20 10.64
1 40.85
2 22.67
3 16.05
4 13.21
5 12.53
6 10.84
7 10.80
8 11.31
9 11.69
10 12.51
11 11.22
12 11.35
13 11.00
14 10.64
15 10.89
16 10.49
17 10.55
18 10.76
19 10.54
20 10.75
1 40.41
2 22.75
3 15.87
4 13.19
5 12.33
6 10.50
7 10.84
8 11.55
9 11.79
10 12.53
11 11.24
12 11.13
13 10.89
14 10.52
15 10.74
16 10.68
17 10.88
18 10.61
19 11.07
20 10.71
1 40.45
2 22.73
3 16.35
4 13.09
5 12.19
6 10.39
7 11.01
8 11.30
9 11.81
10 12.24
11 11.21
12 11.13
13 10.66
14 10.56
15 10.91
16 10.49
17 10.58
18 10.61
19 10.60
20 10.69
1 40.36
2 22.64
3 15.95
4 13.20
5 12.27
6 10.34
7 10.47
8 11.34
9 11.68
10 12.30
11 11.04
12 10.85
13 10.78
14 10.64
15 10.63
16 10.58
17 10.67
18 10.64
19 10.71
20 10.68
1 40.70
2 22.71
3 15.81
4 13.10
5 12.29
6 10.34
7 10.40
8 11.40
9 11.71
10 12.56
11 11.29
12 10.99
13 10.51
14 10.69
15 10.53
16 11.04
17 10.67
18 10.71
19 10.86
20 10.78
1 40.69
2 22.80
3 15.88
4 13.13
5 12.19
6 10.36
7 10.77
8 11.32
9 11.66
10 12.29
11 11.06
12 10.89
13 10.66
14 10.61
15 10.36
16 10.57
17 10.94
18 10.57
19 10.81
20 10.72
1 40.81
2 22.76
3 15.84
4 13.10
5 12.25
6 10.33
7 10.58
8 11.51
9 11.69
10 12.45
11 11.51
12 11.53
13 10.61
14 10.52
15 10.57
16 10.57
17 10.76
18 10.60
19 10.66
20 10.73
1 40.84
2 22.83
3 15.86
4 13.27
5 12.39
6 10.45
7 10.87
8 11.42
9 11.70
10 12.55
11 11.43
12 10.98
13 10.81
14 10.69
15 10.68
16 10.71
17 10.80
18 10.76
19 10.90
20 11.02
1 40.99
2 22.99
3 16.10
4 13.46
5 12.45
6 10.47
7 10.79
8 11.74
9 11.64
10 12.37
11 11.20
12 11.09
13 10.82
14 10.61
15 10.56
16 10.53
17 10.60
18 10.81
19 10.72
20 10.62
1 40.94
2 23.09
3 16.03
4 13.40
5 12.51
6 10.38
7 10.58
8 11.37
9 11.75
10 12.87
11 12.11
12 11.37
13 11.84
14 11.30
15 11.29
16 11.36
17 11.01
18 11.37
19 11.07
20 10.94
+30 -15
View File
@@ -1,8 +1,9 @@
# tag::PRIMES_PROC_TOP[]
from time import perf_counter
from typing import Tuple, List, NamedTuple
from multiprocessing import Process, SimpleQueue # <1>
from typing import Tuple, NamedTuple
from multiprocessing import Process, SimpleQueue, cpu_count # <1>
from multiprocessing import queues # <2>
import sys
from primes import is_prime, NUMBERS
@@ -10,33 +11,47 @@ class Result(NamedTuple): # <3>
flag: bool
elapsed: float
JobQueue = queues.SimpleQueue[Tuple[int, Result]] # <4>
JobQueue = queues.SimpleQueue[int] # <4>
ResultQueue = queues.SimpleQueue[Tuple[int, Result]] # <5>
def check(n: int) -> Result: # <5>
def check(n: int) -> Result: # <6>
t0 = perf_counter()
res = is_prime(n)
return Result(res, perf_counter() - t0)
def job(n: int, results: JobQueue) -> None: # <6>
results.put((n, check(n))) # <7>
def worker(jobs: JobQueue, results: ResultQueue) -> None: # <7>
while n := jobs.get(): # <8>
result = check(n) # <9>
results.put((n, result)) # <10>
# end::PRIMES_PROC_TOP[]
# tag::PRIMES_PROC_MAIN[]
def main() -> None:
if len(sys.argv) < 2: # <1>
workers = cpu_count()
else:
workers = int(sys.argv[1])
t0 = perf_counter()
results: JobQueue = SimpleQueue() # <1>
workers: List[Process] = [] # <2>
jobs: JobQueue = SimpleQueue() # <2>
results: ResultQueue = SimpleQueue()
for n in NUMBERS:
worker = Process(target=job, args=(n, results)) # <3>
worker.start() # <4>
workers.append(worker) # <5>
print(f'Checking {len(NUMBERS)} numbers with {workers} processes:')
for _ in workers: # <6>
for n in NUMBERS: # <3>
jobs.put(n)
for _ in range(workers):
proc = Process(target=worker, args=(jobs, results)) # <4>
proc.start() # <5>
jobs.put(0) # <6>
while True:
n, (prime, elapsed) = results.get() # <7>
label = 'P' if prime else ' '
print(f'{n:16} {label} {elapsed:9.6f}s')
print(f'{n:16} {label} {elapsed:9.6f}s') # <8>
if jobs.empty(): # <9>
break
time = perf_counter() - t0
print('Total time:', f'{time:0.2f}s')
+2
View File
@@ -0,0 +1,2 @@
#/bin/bash
for i in {1..20}; do echo -n $i; python3 procs.py $i | tail -1; done
@@ -0,0 +1,40 @@
# spinner_async_experiment.py
# credits: Example by Luciano Ramalho inspired by
# Michele Simionato's multiprocessing example in the python-list:
# https://mail.python.org/pipermail/python-list/2009-February/675659.html
import asyncio
import itertools
import primes
async def spin(msg: str) -> None:
for char in itertools.cycle(r'\|/-'):
status = f'\r{char} {msg}'
print(status, flush=True, end='')
try:
await asyncio.sleep(.1)
except asyncio.CancelledError:
break
print('THIS WILL NEVER BE OUTPUT')
async def check(n: int) -> int:
return primes.is_prime(n) # <4>
async def supervisor(n: int) -> int:
spinner = asyncio.create_task(spin('thinking!')) # <1>
print('spinner object:', spinner) # <2>
result = await check(n) # <3>
spinner.cancel() # <5>
return result
# end::SPINNER_ASYNC_EXPERIMENT[]
def main() -> None:
n = 5_000_111_000_222_021
result = asyncio.run(supervisor(n))
msg = 'is' if result else 'is not'
print(f'{n:,} {msg} prime')
if __name__ == '__main__':
main()
@@ -0,0 +1,59 @@
# spinner_async_experiment.py
# credits: Example by Luciano Ramalho inspired by
# Michele Simionato's multiprocessing example in the python-list:
# https://mail.python.org/pipermail/python-list/2009-February/675659.html
import asyncio
import itertools
import math
# tag::SPINNER_ASYNC_NAP[]
async def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
sleep = asyncio.sleep # <1>
root = int(math.floor(math.sqrt(n)))
for i in range(3, root + 1, 2):
if n % i == 0:
return False
if i % 100_000 == 1: # <2>
await sleep(0)
return True
# end::SPINNER_ASYNC_NAP[]
async def spin(msg: str) -> None:
for char in itertools.cycle(r'\|/-'):
status = f'\r{char} {msg}'
print(status, flush=True, end='')
try:
await asyncio.sleep(.1)
except asyncio.CancelledError:
break
blanks = ' ' * len(status)
print(f'\r{blanks}\r', end='')
async def check(n: int) -> int:
return await is_prime(n) # <4>
async def supervisor(n: int) -> int:
spinner = asyncio.create_task(spin('thinking!')) # <1>
print('spinner object:', spinner) # <2>
result = await check(n) # <3>
spinner.cancel() # <5>
return result
def main() -> None:
n = 5_000_111_000_222_021
result = asyncio.run(supervisor(n))
msg = 'is' if result else 'is not'
print(f'{n:,} {msg} prime')
if __name__ == '__main__':
main()
@@ -0,0 +1,44 @@
# spinner_prime_proc.py
# credits: Adapted from Michele Simionato's
# multiprocessing example in the python-list:
# https://mail.python.org/pipermail/python-list/2009-February/675659.html
from multiprocessing import Process, Event
from multiprocessing import synchronize
import itertools
import time
from primes import is_prime
def spin(msg: str, done: synchronize.Event) -> None: # <1>
for char in itertools.cycle(r'\|/-'): # <2>
status = f'\r{char} {msg}' # <3>
print(status, end='', flush=True)
if done.wait(.1): # <4>
break # <5>
blanks = ' ' * len(status)
print(f'\r{blanks}\r', end='') # <6>
def check(n: int) -> int:
return is_prime(n)
def supervisor(n: int) -> int: # <1>
done = Event() # <2>
spinner = Process(target=spin,
args=('thinking!', done)) # <3>
print('spinner object:', spinner) # <4>
spinner.start() # <5>
result = check(n) # <6>
done.set() # <7>
spinner.join() # <8>
return result
def main() -> None:
n = 5_000_111_000_222_021
result = supervisor(n) # <9>
msg = 'is' if result else 'is not'
print(f'{n:,} {msg} prime')
if __name__ == '__main__':
main()
@@ -0,0 +1,43 @@
# spinner_prime_thread.py
# credits: Adapted from Michele Simionato's
# multiprocessing example in the python-list:
# https://mail.python.org/pipermail/python-list/2009-February/675659.html
from threading import Thread, Event
import itertools
import time
from primes import is_prime
def spin(msg: str, done: Event) -> None: # <1>
for char in itertools.cycle(r'\|/-'): # <2>
status = f'\r{char} {msg}' # <3>
print(status, end='', flush=True)
if done.wait(.1): # <4>
break # <5>
blanks = ' ' * len(status)
print(f'\r{blanks}\r', end='') # <6>
def check(n: int) -> int:
return is_prime(n)
def supervisor(n: int) -> int: # <1>
done = Event() # <2>
spinner = Thread(target=spin,
args=('thinking!', done)) # <3>
print('spinner object:', spinner) # <4>
spinner.start() # <5>
result = check(n) # <6>
done.set() # <7>
spinner.join() # <8>
return result
def main() -> None:
n = 5_000_111_000_222_021
result = supervisor(n) # <9>
msg = 'is' if result else 'is not'
print(f'{n:,} {msg} prime')
if __name__ == '__main__':
main()
+437
View File
@@ -0,0 +1,437 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([42.05,\n",
" 40.47,\n",
" 40.81,\n",
" 40.85,\n",
" 40.41,\n",
" 40.45,\n",
" 40.36,\n",
" 40.7,\n",
" 40.69,\n",
" 40.81,\n",
" 40.84,\n",
" 40.99,\n",
" 40.94],\n",
" [11.07,\n",
" 11.28,\n",
" 10.64,\n",
" 10.75,\n",
" 10.71,\n",
" 10.69,\n",
" 10.68,\n",
" 10.78,\n",
" 10.72,\n",
" 10.73,\n",
" 11.02,\n",
" 10.62,\n",
" 10.94])"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lines = \"\"\"1 42.05\n",
"2 22.81\n",
"3 15.95\n",
"4 13.28\n",
"5 12.27\n",
"6 10.38\n",
"7 11.00\n",
"8 11.41\n",
"9 12.17\n",
"10 12.69\n",
"11 11.34\n",
"12 11.35\n",
"13 10.88\n",
"14 11.63\n",
"15 11.79\n",
"16 11.49\n",
"17 11.29\n",
"18 10.78\n",
"19 10.92\n",
"20 11.07\n",
"1 40.47\n",
"2 22.93\n",
"3 15.88\n",
"4 13.25\n",
"5 12.22\n",
"6 10.95\n",
"7 10.81\n",
"8 11.26\n",
"9 11.96\n",
"10 12.43\n",
"11 11.19\n",
"12 10.91\n",
"13 11.03\n",
"14 10.56\n",
"15 10.62\n",
"16 11.73\n",
"17 11.00\n",
"18 12.81\n",
"19 12.38\n",
"20 11.28\n",
"1 40.81\n",
"2 22.79\n",
"3 15.83\n",
"4 13.27\n",
"5 12.33\n",
"6 10.65\n",
"7 10.94\n",
"8 11.48\n",
"9 11.78\n",
"10 12.78\n",
"11 11.31\n",
"12 10.97\n",
"13 10.80\n",
"14 10.93\n",
"15 10.69\n",
"16 10.57\n",
"17 10.54\n",
"18 10.55\n",
"19 10.79\n",
"20 10.64\n",
"1 40.85\n",
"2 22.67\n",
"3 16.05\n",
"4 13.21\n",
"5 12.53\n",
"6 10.84\n",
"7 10.80\n",
"8 11.31\n",
"9 11.69\n",
"10 12.51\n",
"11 11.22\n",
"12 11.35\n",
"13 11.00\n",
"14 10.64\n",
"15 10.89\n",
"16 10.49\n",
"17 10.55\n",
"18 10.76\n",
"19 10.54\n",
"20 10.75\n",
"1 40.41\n",
"2 22.75\n",
"3 15.87\n",
"4 13.19\n",
"5 12.33\n",
"6 10.50\n",
"7 10.84\n",
"8 11.55\n",
"9 11.79\n",
"10 12.53\n",
"11 11.24\n",
"12 11.13\n",
"13 10.89\n",
"14 10.52\n",
"15 10.74\n",
"16 10.68\n",
"17 10.88\n",
"18 10.61\n",
"19 11.07\n",
"20 10.71\n",
"1 40.45\n",
"2 22.73\n",
"3 16.35\n",
"4 13.09\n",
"5 12.19\n",
"6 10.39\n",
"7 11.01\n",
"8 11.30\n",
"9 11.81\n",
"10 12.24\n",
"11 11.21\n",
"12 11.13\n",
"13 10.66\n",
"14 10.56\n",
"15 10.91\n",
"16 10.49\n",
"17 10.58\n",
"18 10.61\n",
"19 10.60\n",
"20 10.69\n",
"1 40.36\n",
"2 22.64\n",
"3 15.95\n",
"4 13.20\n",
"5 12.27\n",
"6 10.34\n",
"7 10.47\n",
"8 11.34\n",
"9 11.68\n",
"10 12.30\n",
"11 11.04\n",
"12 10.85\n",
"13 10.78\n",
"14 10.64\n",
"15 10.63\n",
"16 10.58\n",
"17 10.67\n",
"18 10.64\n",
"19 10.71\n",
"20 10.68\n",
"1 40.70\n",
"2 22.71\n",
"3 15.81\n",
"4 13.10\n",
"5 12.29\n",
"6 10.34\n",
"7 10.40\n",
"8 11.40\n",
"9 11.71\n",
"10 12.56\n",
"11 11.29\n",
"12 10.99\n",
"13 10.51\n",
"14 10.69\n",
"15 10.53\n",
"16 11.04\n",
"17 10.67\n",
"18 10.71\n",
"19 10.86\n",
"20 10.78\n",
"1 40.69\n",
"2 22.80\n",
"3 15.88\n",
"4 13.13\n",
"5 12.19\n",
"6 10.36\n",
"7 10.77\n",
"8 11.32\n",
"9 11.66\n",
"10 12.29\n",
"11 11.06\n",
"12 10.89\n",
"13 10.66\n",
"14 10.61\n",
"15 10.36\n",
"16 10.57\n",
"17 10.94\n",
"18 10.57\n",
"19 10.81\n",
"20 10.72\n",
"1 40.81\n",
"2 22.76\n",
"3 15.84\n",
"4 13.10\n",
"5 12.25\n",
"6 10.33\n",
"7 10.58\n",
"8 11.51\n",
"9 11.69\n",
"10 12.45\n",
"11 11.51\n",
"12 11.53\n",
"13 10.61\n",
"14 10.52\n",
"15 10.57\n",
"16 10.57\n",
"17 10.76\n",
"18 10.60\n",
"19 10.66\n",
"20 10.73\n",
"1 40.84\n",
"2 22.83\n",
"3 15.86\n",
"4 13.27\n",
"5 12.39\n",
"6 10.45\n",
"7 10.87\n",
"8 11.42\n",
"9 11.70\n",
"10 12.55\n",
"11 11.43\n",
"12 10.98\n",
"13 10.81\n",
"14 10.69\n",
"15 10.68\n",
"16 10.71\n",
"17 10.80\n",
"18 10.76\n",
"19 10.90\n",
"20 11.02\n",
"1 40.99\n",
"2 22.99\n",
"3 16.10\n",
"4 13.46\n",
"5 12.45\n",
"6 10.47\n",
"7 10.79\n",
"8 11.74\n",
"9 11.64\n",
"10 12.37\n",
"11 11.20\n",
"12 11.09\n",
"13 10.82\n",
"14 10.61\n",
"15 10.56\n",
"16 10.53\n",
"17 10.60\n",
"18 10.81\n",
"19 10.72\n",
"20 10.62\n",
"1 40.94\n",
"2 23.09\n",
"3 16.03\n",
"4 13.40\n",
"5 12.51\n",
"6 10.38\n",
"7 10.58\n",
"8 11.37\n",
"9 11.75\n",
"10 12.87\n",
"11 12.11\n",
"12 11.37\n",
"13 11.84\n",
"14 11.30\n",
"15 11.29\n",
"16 11.36\n",
"17 11.01\n",
"18 11.37\n",
"19 11.07\n",
"20 10.94\"\"\"\n",
"\n",
"from collections import defaultdict\n",
"\n",
"times = defaultdict(list)\n",
"for line in lines.split('\\n'):\n",
" n, s = line.strip().split()\n",
" n, s = int(n), float(s)\n",
" times[n].append(s)\n",
"\n",
"times[1], times[20]"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10.39"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from statistics import median, mean\n",
"\n",
"median_times = []\n",
"mean_times = []\n",
"for procs, ts in times.items():\n",
" median_times.append(median(ts))\n",
" mean_times.append(mean(ts))\n",
" \n",
"min(median_times)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"df=pd.DataFrame(\n",
" {'procs': range(1,21),\n",
" 'median': median_times})"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5, 0, 'processes')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.plot('procs', 'median', data=df, marker='+')\n",
"plt.ylim([0, 50])\n",
"plt.ylabel('time (s)')\n",
"plt.xlabel('processes')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Dúvidas\n",
"\n",
"1. O eixo x são valores discretos: a quantidade de processos em uso. Como faço para que o eixo x seja marcado com os números de 1 a 20, um por um (20 ticks)? \n",
"2. Como alargar o retângulo do gráfico uns 50%, para que os números no eixo x não fiquem muito apertados?\n",
"3. Como exibir uma linha horizontal na altura do valor mínimo, que é 10.39?\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
+30 -13
View File
@@ -1,38 +1,55 @@
from time import perf_counter
from typing import Tuple, List, NamedTuple
from typing import Tuple, NamedTuple
from threading import Thread
from queue import SimpleQueue
import sys
import os
from primes import is_prime, NUMBERS
class Result(NamedTuple): # <3>
class Result(NamedTuple):
flag: bool
elapsed: float
JobQueue = SimpleQueue[Tuple[int, Result]] # <4>
JobQueue = SimpleQueue[int]
ResultQueue = SimpleQueue[Tuple[int, Result]]
def check(n: int) -> Result: # <5>
def check(n: int) -> Result:
t0 = perf_counter()
res = is_prime(n)
return Result(res, perf_counter() - t0)
def job(n: int, results: JobQueue) -> None: # <6>
results.put((n, check(n))) # <7>
def worker(jobs: JobQueue, results: ResultQueue) -> None:
while n := jobs.get():
result = check(n)
results.put((n, result))
def main() -> None:
if len(sys.argv) < 2: # <1>
workers = os.cpu_count() or 1 # make mypy happy
else:
workers = int(sys.argv[1])
t0 = perf_counter()
results: JobQueue = SimpleQueue() # <1>
workers: List[Thread] = [] # <2>
jobs: JobQueue = SimpleQueue() # <2>
results: ResultQueue = SimpleQueue()
for n in NUMBERS:
worker = Thread(target=job, args=(n, results)) # <3>
worker.start() # <4>
workers.append(worker) # <5>
print(f'Checking {len(NUMBERS)} numbers with {workers} threads:')
for _ in workers: # <6>
for n in NUMBERS: # <3>
jobs.put(n)
for _ in range(workers):
proc = Thread(target=worker, args=(jobs, results)) # <4>
proc.start() # <5>
jobs.put(0) # <6>
while True:
n, (prime, elapsed) = results.get() # <7>
label = 'P' if prime else ' '
print(f'{n:16} {label} {elapsed:9.6f}s')
if jobs.empty(): # <8>
break
time = perf_counter() - t0
print('Total time:', f'{time:0.2f}s')