Skip to content

Instantly share code, notes, and snippets.

@yoshan0921
Last active December 11, 2023 11:13
Show Gist options
  • Save yoshan0921/154616d2808b0c19eaa9a8d5211ad4df to your computer and use it in GitHub Desktop.
Save yoshan0921/154616d2808b0c19eaa9a8d5211ad4df to your computer and use it in GitHub Desktop.
import multiprocessing
import threading
import asyncio
import time
import logging
WORK_MULTIPLICITY = 3
CPU_LOAD = 10**7
IO_LATENCY = 2
start = 0.0
logging.basicConfig(
level=logging.DEBUG,
format='%(processName)s_%(threadName)s: %(message)s'
)
# For synchronous, threading, multiprocessing
def worker(n, start_time):
logging.debug(f"worker-{n}: start")
logging.debug(f"worker-{n}: checkpoint1 = {
time.time() - start_time:06.3f}")
# cpu-bound
for i in range(CPU_LOAD):
# check progress
if i == CPU_LOAD//4*1:
logging.debug(
f"worker-{n}: checkpoint1-1 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*2:
logging.debug(
f"worker-{n}: checkpoint1-2 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*3:
logging.debug(
f"worker-{n}: checkpoint1-3 = {time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: checkpoint2 = {
time.time() - start_time:06.3f}")
# io-bound
time.sleep(IO_LATENCY)
logging.debug(f"worker-{n}: checkpoint3 = {
time.time() - start_time:06.3f}")
# cpu-bound
for i in range(CPU_LOAD):
# check progress
if i == CPU_LOAD//4*1:
logging.debug(
f"worker-{n}: checkpoint3-1 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*2:
logging.debug(
f"worker-{n}: checkpoint3-2 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*3:
logging.debug(
f"worker-{n}: checkpoint3-3 = {time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: checkpoint4 = {
time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: end")
# This is wrapper for worker() to separate arguments
def wrap_worker(args):
return worker(*args)
# For asyncio
async def worker_async(n, start_time):
logging.debug(f"worker-{n}: start")
logging.debug(f"worker-{n}: checkpoint1 = {
time.time() - start_time:06.3f}")
# cpu-bound
for i in range(CPU_LOAD):
# check progress
if i == CPU_LOAD//4*1:
logging.debug(
f"worker-{n}: checkpoint1-1 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*2:
logging.debug(
f"worker-{n}: checkpoint1-2 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*3:
logging.debug(
f"worker-{n}: checkpoint1-3 = {time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: checkpoint2 = {
time.time() - start_time:06.3f}")
# io-bound
await asyncio.sleep(IO_LATENCY)
logging.debug(f"worker-{n}: checkpoint3 = {
time.time() - start_time:06.3f}")
# cpu-bound
for i in range(CPU_LOAD):
# check progress
if i == CPU_LOAD//4*1:
logging.debug(
f"worker-{n}: checkpoint3-1 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*2:
logging.debug(
f"worker-{n}: checkpoint3-2 = {time.time() - start_time:06.3f}")
elif i == CPU_LOAD//4*3:
logging.debug(
f"worker-{n}: checkpoint3-3 = {time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: checkpoint4 = {
time.time() - start_time:06.3f}")
logging.debug(f"worker-{n}: end")
if __name__ == '__main__':
# 1.synchronous
logging.debug(f"synchronous: start")
start = time.time()
for i in range(1, WORK_MULTIPLICITY+1):
worker(i, start)
end_1 = time.time() - start
logging.debug(f"synchronous: end = {end_1:06.3f}\n")
# 2.asyncio
logging.debug(f"asyncio: start")
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
*[worker_async(i, start) for i in range(1, WORK_MULTIPLICITY+1)]))
loop.close()
end_2 = time.time() - start
logging.debug(f"asyncio: end = {end_2:06.3f}\n")
# 3.threading
logging.debug(f"threading: start")
start = time.time()
for i in range(1, WORK_MULTIPLICITY+1):
threading.Thread(target=worker, args=(i, start)).start()
for thread in threading.enumerate():
if thread is not threading.current_thread():
thread.join()
end_3 = time.time() - start
logging.debug(f"threading: end = {end_3:06.3f}\n")
# 4.multiprocessing
logging.debug(f"multiprocessing: start")
start = time.time()
args = [(i, start) for i in range(1, WORK_MULTIPLICITY+1)]
with multiprocessing.Pool(processes=WORK_MULTIPLICITY) as pool:
pool.map(wrap_worker, args)
end_4 = time.time() - start
logging.debug(f"multiprocessing: end = {end_4:06.3f}\n")
# Result
print("Result:")
print(f"1.synchronous : {end_1:06.3f} seconds")
print(f"2.asyncio : {end_2:06.3f} seconds")
print(f"3.threading : {end_3:06.3f} seconds")
print(f"4.multiprocessing : {end_4:06.3f} seconds")
yosuke@Yosuke-Hanaoka python-sandbox % /Users/yosuke/.pyenv/versions/3.12.0/bin/python /Users/yosuke/VSCode
/python-sandbox/threading-vs-multiprocessing-vs-asyncio/io-bound.py
MainProcess_MainThread: synchronous: start
MainProcess_MainThread: worker-1: start
MainProcess_MainThread: worker-1: checkpoint1 = 00.000
MainProcess_MainThread: worker-1: checkpoint1-1 = 00.318
MainProcess_MainThread: worker-1: checkpoint1-2 = 00.632
MainProcess_MainThread: worker-1: checkpoint1-3 = 00.951
MainProcess_MainThread: worker-1: checkpoint2 = 01.268
MainProcess_MainThread: worker-1: checkpoint3 = 03.273
MainProcess_MainThread: worker-1: checkpoint3-1 = 03.627
MainProcess_MainThread: worker-1: checkpoint3-2 = 03.944
MainProcess_MainThread: worker-1: checkpoint3-3 = 04.260
MainProcess_MainThread: worker-1: checkpoint4 = 04.577
MainProcess_MainThread: worker-1: end
MainProcess_MainThread: worker-2: start
MainProcess_MainThread: worker-2: checkpoint1 = 04.577
MainProcess_MainThread: worker-2: checkpoint1-1 = 04.896
MainProcess_MainThread: worker-2: checkpoint1-2 = 05.213
MainProcess_MainThread: worker-2: checkpoint1-3 = 05.529
MainProcess_MainThread: worker-2: checkpoint2 = 05.857
MainProcess_MainThread: worker-2: checkpoint3 = 07.863
MainProcess_MainThread: worker-2: checkpoint3-1 = 08.219
MainProcess_MainThread: worker-2: checkpoint3-2 = 08.538
MainProcess_MainThread: worker-2: checkpoint3-3 = 08.853
MainProcess_MainThread: worker-2: checkpoint4 = 09.172
MainProcess_MainThread: worker-2: end
MainProcess_MainThread: worker-3: start
MainProcess_MainThread: worker-3: checkpoint1 = 09.172
MainProcess_MainThread: worker-3: checkpoint1-1 = 09.493
MainProcess_MainThread: worker-3: checkpoint1-2 = 09.812
MainProcess_MainThread: worker-3: checkpoint1-3 = 10.131
MainProcess_MainThread: worker-3: checkpoint2 = 10.447
MainProcess_MainThread: worker-3: checkpoint3 = 12.453
MainProcess_MainThread: worker-3: checkpoint3-1 = 12.811
MainProcess_MainThread: worker-3: checkpoint3-2 = 13.131
MainProcess_MainThread: worker-3: checkpoint3-3 = 13.450
MainProcess_MainThread: worker-3: checkpoint4 = 13.768
MainProcess_MainThread: worker-3: end
MainProcess_MainThread: synchronous: end = 13.768
MainProcess_MainThread: asyncio: start
/Users/yosuke/VSCode/python-sandbox/threading-vs-multiprocessing-vs-asyncio/io-bound.py:140: DeprecationWarning: There is no current event loop
loop = asyncio.get_event_loop()
MainProcess_MainThread: Using selector: KqueueSelector
MainProcess_MainThread: worker-1: start
MainProcess_MainThread: worker-1: checkpoint1 = 00.002
MainProcess_MainThread: worker-1: checkpoint1-1 = 00.315
MainProcess_MainThread: worker-1: checkpoint1-2 = 00.627
MainProcess_MainThread: worker-1: checkpoint1-3 = 00.937
MainProcess_MainThread: worker-1: checkpoint2 = 01.246
MainProcess_MainThread: worker-2: start
MainProcess_MainThread: worker-2: checkpoint1 = 01.246
MainProcess_MainThread: worker-2: checkpoint1-1 = 01.558
MainProcess_MainThread: worker-2: checkpoint1-2 = 01.870
MainProcess_MainThread: worker-2: checkpoint1-3 = 02.182
MainProcess_MainThread: worker-2: checkpoint2 = 02.495
MainProcess_MainThread: worker-3: start
MainProcess_MainThread: worker-3: checkpoint1 = 02.495
MainProcess_MainThread: worker-3: checkpoint1-1 = 02.804
MainProcess_MainThread: worker-3: checkpoint1-2 = 03.118
MainProcess_MainThread: worker-3: checkpoint1-3 = 03.427
MainProcess_MainThread: worker-3: checkpoint2 = 03.736
MainProcess_MainThread: worker-1: checkpoint3 = 03.736
MainProcess_MainThread: worker-1: checkpoint3-1 = 04.050
MainProcess_MainThread: worker-1: checkpoint3-2 = 04.364
MainProcess_MainThread: worker-1: checkpoint3-3 = 04.680
MainProcess_MainThread: worker-1: checkpoint4 = 04.996
MainProcess_MainThread: worker-1: end
MainProcess_MainThread: worker-2: checkpoint3 = 04.996
MainProcess_MainThread: worker-2: checkpoint3-1 = 05.308
MainProcess_MainThread: worker-2: checkpoint3-2 = 05.620
MainProcess_MainThread: worker-2: checkpoint3-3 = 05.935
MainProcess_MainThread: worker-2: checkpoint4 = 06.253
MainProcess_MainThread: worker-2: end
MainProcess_MainThread: worker-3: checkpoint3 = 06.253
MainProcess_MainThread: worker-3: checkpoint3-1 = 06.569
MainProcess_MainThread: worker-3: checkpoint3-2 = 06.886
MainProcess_MainThread: worker-3: checkpoint3-3 = 07.201
MainProcess_MainThread: worker-3: checkpoint4 = 07.517
MainProcess_MainThread: worker-3: end
MainProcess_MainThread: asyncio: end = 07.517
MainProcess_MainThread: threading: start
MainProcess_Thread-1 (worker): worker-1: start
MainProcess_Thread-1 (worker): worker-1: checkpoint1 = 00.000
MainProcess_Thread-2 (worker): worker-2: start
MainProcess_Thread-3 (worker): worker-3: start
MainProcess_Thread-2 (worker): worker-2: checkpoint1 = 00.013
MainProcess_Thread-3 (worker): worker-3: checkpoint1 = 00.032
MainProcess_Thread-1 (worker): worker-1: checkpoint1-1 = 00.900
MainProcess_Thread-2 (worker): worker-2: checkpoint1-1 = 00.997
MainProcess_Thread-3 (worker): worker-3: checkpoint1-1 = 01.029
MainProcess_Thread-1 (worker): worker-1: checkpoint1-2 = 01.869
MainProcess_Thread-2 (worker): worker-2: checkpoint1-2 = 01.953
MainProcess_Thread-3 (worker): worker-3: checkpoint1-2 = 02.002
MainProcess_Thread-1 (worker): worker-1: checkpoint1-3 = 02.862
MainProcess_Thread-2 (worker): worker-2: checkpoint1-3 = 02.888
MainProcess_Thread-3 (worker): worker-3: checkpoint1-3 = 02.969
MainProcess_Thread-2 (worker): worker-2: checkpoint2 = 03.834
MainProcess_Thread-1 (worker): worker-1: checkpoint2 = 03.839
MainProcess_Thread-3 (worker): worker-3: checkpoint2 = 03.874
MainProcess_Thread-2 (worker): worker-2: checkpoint3 = 05.839
MainProcess_Thread-1 (worker): worker-1: checkpoint3 = 05.850
MainProcess_Thread-3 (worker): worker-3: checkpoint3 = 05.881
MainProcess_Thread-2 (worker): worker-2: checkpoint3-1 = 06.808
MainProcess_Thread-1 (worker): worker-1: checkpoint3-1 = 06.852
MainProcess_Thread-3 (worker): worker-3: checkpoint3-1 = 06.862
MainProcess_Thread-2 (worker): worker-2: checkpoint3-2 = 07.779
MainProcess_Thread-1 (worker): worker-1: checkpoint3-2 = 07.822
MainProcess_Thread-3 (worker): worker-3: checkpoint3-2 = 07.826
MainProcess_Thread-2 (worker): worker-2: checkpoint3-3 = 08.735
MainProcess_Thread-3 (worker): worker-3: checkpoint3-3 = 08.786
MainProcess_Thread-1 (worker): worker-1: checkpoint3-3 = 08.796
MainProcess_Thread-2 (worker): worker-2: checkpoint4 = 09.700
MainProcess_Thread-2 (worker): worker-2: end
MainProcess_Thread-1 (worker): worker-1: checkpoint4 = 09.733
MainProcess_Thread-1 (worker): worker-1: end
MainProcess_Thread-3 (worker): worker-3: checkpoint4 = 09.734
MainProcess_Thread-3 (worker): worker-3: end
MainProcess_MainThread: threading: end = 09.734
MainProcess_MainThread: multiprocessing: start
SpawnPoolWorker-1_MainThread: worker-1: start
SpawnPoolWorker-1_MainThread: worker-1: checkpoint1 = 00.135
SpawnPoolWorker-3_MainThread: worker-2: start
SpawnPoolWorker-3_MainThread: worker-2: checkpoint1 = 00.136
SpawnPoolWorker-2_MainThread: worker-3: start
SpawnPoolWorker-2_MainThread: worker-3: checkpoint1 = 00.136
SpawnPoolWorker-2_MainThread: worker-3: checkpoint1-1 = 00.531
SpawnPoolWorker-3_MainThread: worker-2: checkpoint1-1 = 00.536
SpawnPoolWorker-1_MainThread: worker-1: checkpoint1-1 = 00.547
SpawnPoolWorker-2_MainThread: worker-3: checkpoint1-2 = 00.915
SpawnPoolWorker-3_MainThread: worker-2: checkpoint1-2 = 00.922
SpawnPoolWorker-1_MainThread: worker-1: checkpoint1-2 = 00.943
SpawnPoolWorker-2_MainThread: worker-3: checkpoint1-3 = 01.293
SpawnPoolWorker-3_MainThread: worker-2: checkpoint1-3 = 01.299
SpawnPoolWorker-1_MainThread: worker-1: checkpoint1-3 = 01.334
SpawnPoolWorker-2_MainThread: worker-3: checkpoint2 = 01.649
SpawnPoolWorker-3_MainThread: worker-2: checkpoint2 = 01.656
SpawnPoolWorker-1_MainThread: worker-1: checkpoint2 = 01.694
SpawnPoolWorker-2_MainThread: worker-3: checkpoint3 = 03.654
SpawnPoolWorker-3_MainThread: worker-2: checkpoint3 = 03.661
SpawnPoolWorker-1_MainThread: worker-1: checkpoint3 = 03.696
SpawnPoolWorker-2_MainThread: worker-3: checkpoint3-1 = 04.057
SpawnPoolWorker-3_MainThread: worker-2: checkpoint3-1 = 04.059
SpawnPoolWorker-1_MainThread: worker-1: checkpoint3-1 = 04.086
SpawnPoolWorker-3_MainThread: worker-2: checkpoint3-2 = 04.418
SpawnPoolWorker-2_MainThread: worker-3: checkpoint3-2 = 04.419
SpawnPoolWorker-1_MainThread: worker-1: checkpoint3-2 = 04.464
SpawnPoolWorker-3_MainThread: worker-2: checkpoint3-3 = 04.775
SpawnPoolWorker-2_MainThread: worker-3: checkpoint3-3 = 04.778
SpawnPoolWorker-1_MainThread: worker-1: checkpoint3-3 = 04.834
SpawnPoolWorker-3_MainThread: worker-2: checkpoint4 = 05.129
SpawnPoolWorker-3_MainThread: worker-2: end
SpawnPoolWorker-2_MainThread: worker-3: checkpoint4 = 05.134
SpawnPoolWorker-2_MainThread: worker-3: end
SpawnPoolWorker-1_MainThread: worker-1: checkpoint4 = 05.202
SpawnPoolWorker-1_MainThread: worker-1: end
MainProcess_MainThread: multiprocessing: end = 05.204
Result:
1.synchronous : 13.768 seconds
2.asyncio : 07.517 seconds
3.threading : 09.734 seconds
4.multiprocessing : 05.204 seconds
yosuke@Yosuke-Hanaoka python-sandbox %
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment