renumbering chapters >= 19
This commit is contained in:
1 parent
cbd13885fc
commit
4ae4096c4c
154 files changed
+7
-1134
No files matched your search
@@ -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
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import math
|
||||
|
||||
PRIME_FIXTURE = [
|
||||
(2, True),
|
||||
(142702110479723, True),
|
||||
(299593572317531, True),
|
||||
(3333333333333301, True),
|
||||
(3333333333333333, False),
|
||||
(3333335652092209, False),
|
||||
(4444444444444423, True),
|
||||
(4444444444444444, False),
|
||||
(4444444488888889, False),
|
||||
(5555553133149889, False),
|
||||
(5555555555555503, True),
|
||||
(5555555555555555, False),
|
||||
(6666666666666666, False),
|
||||
(6666666666666719, True),
|
||||
(6666667141414921, False),
|
||||
(7777777536340681, False),
|
||||
(7777777777777753, True),
|
||||
(7777777777777777, False),
|
||||
(9999999999999917, True),
|
||||
(9999999999999999, False),
|
||||
]
|
||||
|
||||
NUMBERS = [n for n, _ in PRIME_FIXTURE]
|
||||
|
||||
# tag::IS_PRIME[]
|
||||
def is_prime(n: int) -> bool:
|
||||
if n < 2:
|
||||
return False
|
||||
if n == 2:
|
||||
return True
|
||||
if n % 2 == 0:
|
||||
return False
|
||||
|
||||
root = math.isqrt(n)
|
||||
for i in range(3, root + 1, 2):
|
||||
if n % i == 0:
|
||||
return False
|
||||
return True
|
||||
# end::IS_PRIME[]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
for n, prime in PRIME_FIXTURE:
|
||||
prime_res = is_prime(n)
|
||||
assert prime_res == prime
|
||||
print(n, prime)
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
procs.py: shows that multiprocessing on a multicore machine
|
||||
can be faster than sequential code for CPU-intensive work.
|
||||
"""
|
||||
|
||||
# tag::PRIMES_PROC_TOP[]
|
||||
import sys
|
||||
from time import perf_counter
|
||||
from typing import NamedTuple
|
||||
from multiprocessing import Process, SimpleQueue, cpu_count # <1>
|
||||
from multiprocessing import queues # <2>
|
||||
|
||||
from primes import is_prime, NUMBERS
|
||||
|
||||
class PrimeResult(NamedTuple): # <3>
|
||||
n: int
|
||||
prime: bool
|
||||
elapsed: float
|
||||
|
||||
JobQueue = queues.SimpleQueue[int] # <4>
|
||||
ResultQueue = queues.SimpleQueue[PrimeResult] # <5>
|
||||
|
||||
def check(n: int) -> PrimeResult: # <6>
|
||||
t0 = perf_counter()
|
||||
res = is_prime(n)
|
||||
return PrimeResult(n, res, perf_counter() - t0)
|
||||
|
||||
def worker(jobs: JobQueue, results: ResultQueue) -> None: # <7>
|
||||
while n := jobs.get(): # <8>
|
||||
results.put(check(n)) # <9>
|
||||
# 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])
|
||||
|
||||
print(f'Checking {len(NUMBERS)} numbers with {workers} processes:')
|
||||
|
||||
jobs: JobQueue = SimpleQueue() # <2>
|
||||
results: ResultQueue = SimpleQueue()
|
||||
t0 = perf_counter()
|
||||
|
||||
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') # <8>
|
||||
if jobs.empty(): # <9>
|
||||
break
|
||||
|
||||
elapsed = perf_counter() - t0
|
||||
print(f'Total time: {elapsed:.2f}s')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# end::PRIMES_PROC_MAIN[]
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import math
|
||||
|
||||
PRIME_FIXTURE = [
|
||||
(2, True),
|
||||
(142702110479723, True),
|
||||
(299593572317531, True),
|
||||
(3333333333333301, True),
|
||||
(3333333333333333, False),
|
||||
(3333335652092209, False),
|
||||
(4444444444444423, True),
|
||||
(4444444444444444, False),
|
||||
(4444444488888889, False),
|
||||
(5555553133149889, False),
|
||||
(5555555555555503, True),
|
||||
(5555555555555555, False),
|
||||
(6666666666666666, False),
|
||||
(6666666666666719, True),
|
||||
(6666667141414921, False),
|
||||
(7777777536340681, False),
|
||||
(7777777777777753, True),
|
||||
(7777777777777777, False),
|
||||
(9999999999999917, True),
|
||||
(9999999999999999, False),
|
||||
]
|
||||
|
||||
NUMBERS = [n for n, _ in PRIME_FIXTURE]
|
||||
|
||||
# tag::IS_PRIME[]
|
||||
def is_prime(n: int) -> bool:
|
||||
if n < 2:
|
||||
return False
|
||||
if n == 2:
|
||||
return True
|
||||
if n % 2 == 0:
|
||||
return False
|
||||
|
||||
root = math.floor(math.sqrt(n))
|
||||
for i in range(3, root + 1, 2):
|
||||
if n % i == 0:
|
||||
return False
|
||||
return True
|
||||
# end::IS_PRIME[]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
for n, prime in PRIME_FIXTURE:
|
||||
prime_res = is_prime(n)
|
||||
assert prime_res == prime
|
||||
print(n, prime)
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
procs.py: shows that multiprocessing on a multicore machine
|
||||
can be faster than sequential code for CPU-intensive work.
|
||||
"""
|
||||
|
||||
# tag::PRIMES_PROC_TOP[]
|
||||
import sys
|
||||
from time import perf_counter
|
||||
from typing import NamedTuple
|
||||
from multiprocessing import Process, SimpleQueue, cpu_count # <1>
|
||||
from multiprocessing import queues # <2>
|
||||
|
||||
from primes import is_prime, NUMBERS
|
||||
|
||||
class PrimeResult(NamedTuple): # <3>
|
||||
n: int
|
||||
prime: bool
|
||||
elapsed: float
|
||||
|
||||
JobQueue = queues.SimpleQueue # <4>
|
||||
ResultQueue = queues.SimpleQueue # <5>
|
||||
|
||||
def check(n: int) -> PrimeResult: # <6>
|
||||
t0 = perf_counter()
|
||||
res = is_prime(n)
|
||||
return PrimeResult(n, res, perf_counter() - t0)
|
||||
|
||||
def worker(jobs: JobQueue, results: ResultQueue) -> None: # <7>
|
||||
while True:
|
||||
n = jobs.get() # <8>
|
||||
if n == 0:
|
||||
break
|
||||
results.put(check(n)) # <9>
|
||||
# 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])
|
||||
|
||||
print(f'Checking {len(NUMBERS)} numbers with {workers} processes:')
|
||||
|
||||
jobs: JobQueue = SimpleQueue() # <2>
|
||||
results: ResultQueue = SimpleQueue()
|
||||
t0 = perf_counter()
|
||||
|
||||
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') # <8>
|
||||
if jobs.empty(): # <9>
|
||||
break
|
||||
|
||||
elapsed = perf_counter() - t0
|
||||
print(f'Total time: {elapsed:.2f}s')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# end::PRIMES_PROC_MAIN[]
|
||||
Executable
+2
@@ -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,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
sequential.py: baseline for comparing sequential, multiprocessing,
|
||||
and threading code for CPU-intensive work.
|
||||
"""
|
||||
|
||||
from time import perf_counter
|
||||
from typing import NamedTuple
|
||||
|
||||
from primes import is_prime, NUMBERS
|
||||
|
||||
class Result(NamedTuple): # <1>
|
||||
prime: bool
|
||||
elapsed: float
|
||||
|
||||
def check(n: int) -> Result: # <2>
|
||||
t0 = perf_counter()
|
||||
prime = is_prime(n)
|
||||
return Result(prime, perf_counter() - t0)
|
||||
|
||||
def main() -> None:
|
||||
print(f'Checking {len(NUMBERS)} numbers sequentially:')
|
||||
t0 = perf_counter()
|
||||
for n in NUMBERS: # <3>
|
||||
prime, elapsed = check(n)
|
||||
label = 'P' if prime else ' '
|
||||
print(f'{n:16} {label} {elapsed:9.6f}s')
|
||||
|
||||
elapsed = perf_counter() - t0 # <4>
|
||||
print(f'Total time: {elapsed:.2f}s')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -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,58 @@
|
||||
# spinner_prime_async_nap.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::PRIME_NAP[]
|
||||
async def is_prime(n):
|
||||
if n < 2:
|
||||
return False
|
||||
if n == 2:
|
||||
return True
|
||||
if n % 2 == 0:
|
||||
return False
|
||||
|
||||
root = math.isqrt(n)
|
||||
for i in range(3, root + 1, 2):
|
||||
if n % i == 0:
|
||||
return False
|
||||
if i % 100_000 == 1: # <2>
|
||||
await asyncio.sleep(0)
|
||||
return True
|
||||
# end::PRIME_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,43 @@
|
||||
# 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
|
||||
|
||||
import itertools
|
||||
from multiprocessing import Process, Event
|
||||
from multiprocessing import synchronize
|
||||
|
||||
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(f'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,42 @@
|
||||
# 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
|
||||
|
||||
import itertools
|
||||
from threading import Thread, Event
|
||||
|
||||
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(f'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,474 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"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\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"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": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"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": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"10.39"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"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": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1 40.81\n",
|
||||
"2 22.79\n",
|
||||
"3 15.88\n",
|
||||
"4 13.21\n",
|
||||
"5 12.29\n",
|
||||
"6 10.39\n",
|
||||
"7 10.8\n",
|
||||
"8 11.4\n",
|
||||
"9 11.71\n",
|
||||
"10 12.51\n",
|
||||
"11 11.24\n",
|
||||
"12 11.09\n",
|
||||
"13 10.81\n",
|
||||
"14 10.64\n",
|
||||
"15 10.68\n",
|
||||
"16 10.58\n",
|
||||
"17 10.76\n",
|
||||
"18 10.71\n",
|
||||
"19 10.81\n",
|
||||
"20 10.73\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for i, t, in enumerate(median_times, 1):\n",
|
||||
" print(i, t)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"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": 6,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 576x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plt.figure(figsize=(8, 4))\n",
|
||||
"plt.plot('procs', 'median', data=df, marker='+', markersize=10, linestyle='None')\n",
|
||||
"plt.axhline(min(median_times), linestyle=(0, (1, 3)), color='red')\n",
|
||||
"plt.ylim([0, 50])\n",
|
||||
"plt.ylabel('time (s)')\n",
|
||||
"plt.xlabel('processes')\n",
|
||||
"plt.xticks([i for i in range(1, 21)])\n",
|
||||
"print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Thanks to these generous twitizens for helping me customize this graph:\n",
|
||||
"\n",
|
||||
"* [@hcpyz](https://twitter.com/hcpyz/status/1355310776916062211)\n",
|
||||
"* [@guilhrme_alves](https://twitter.com/guilhrme_alves/status/1355314798796414982)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
threads.py: shows that Python threads are slower than
|
||||
sequential code for CPU-intensive work.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from queue import SimpleQueue
|
||||
from time import perf_counter
|
||||
from typing import NamedTuple
|
||||
from threading import Thread
|
||||
|
||||
from primes import is_prime, NUMBERS
|
||||
|
||||
class PrimeResult(NamedTuple): # <3>
|
||||
n: int
|
||||
prime: bool
|
||||
elapsed: float
|
||||
|
||||
JobQueue = SimpleQueue[int]
|
||||
ResultQueue = SimpleQueue[PrimeResult]
|
||||
|
||||
def check(n: int) -> PrimeResult:
|
||||
t0 = perf_counter()
|
||||
res = is_prime(n)
|
||||
return PrimeResult(n, res, perf_counter() - t0)
|
||||
|
||||
def worker(jobs: JobQueue, results: ResultQueue) -> None:
|
||||
while n := jobs.get():
|
||||
results.put(check(n))
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) < 2: # <1>
|
||||
workers = os.cpu_count() or 1 # make mypy happy
|
||||
else:
|
||||
workers = int(sys.argv[1])
|
||||
|
||||
print(f'Checking {len(NUMBERS)} numbers with {workers} threads:')
|
||||
|
||||
jobs: JobQueue = SimpleQueue() # <2>
|
||||
results: ResultQueue = SimpleQueue()
|
||||
t0 = perf_counter()
|
||||
|
||||
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
|
||||
|
||||
elapsed = perf_counter() - t0
|
||||
print(f'Total time: {elapsed:.2f}s')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user