-
ํ์ด์ ์ ํ์ค ๊ตฌํ
-
2๋จ๊ณ๋ก ๊ตฌ์ฑ
- ์์ค ์ฝ๋๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํด์ ๋ฐ์ดํธ์ฝ๋๋ก ๋ณํ
- 8๋นํธ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ๋ ์ ์์ค ํ๋ก๊ทธ๋จ ํํ
- 3.6 ๋ถํฐ 16๋นํธ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉ, wordcode
- 8๋นํธ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ๋ ์ ์์ค ํ๋ก๊ทธ๋จ ํํ
- ๋ฐ์ดํธ์ฝ๋๋ฅผ ์คํ ๊ธฐ๋ฐ ์ธํฐํ๋ฆฌํฐ๋ฅผ ํตํด ์คํ
- ๋ฐ์ดํธ์ฝ๋ ์ธํฐํ๋ฆฌํฐ์ ์ ์ญ ์ธํฐํ๋ฆฌํฐ ๋ฝ(GIL, Global Interpreter Lock) ์ฌ์ฉํ์ฌ ์ผ๊ด์ฑ ๊ฐ์ ์ ์ง
- GIL
- ์ํธ ๋ฐฐ์ ๋ฝ
- ๋ฎคํ ์ค
- ์ ์ ํ ๋ฉํฐ์ค๋ ๋๋ก ์ธํด ์ํฅ์ ๋ฐ๋ ๊ฒ์ ๋ฐฉ์ง
- ํ ์ค๋ ๋๊ฐ ๋ค๋ฅธ ์ค๋ ๋์ ์คํ์ ์ค๊ฐ์ ์ธํฐ๋ฝํธ์ํค๊ณ ์ ์ด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์
- ์ธํฐ๋ฝํธ๊ฐ ์๊ธฐ์น ๋ชปํ ๋ ๋ฐ์ํ๋ฉด ์ธํฐํ๋ฆฌํฐ์ ์ํ๊ฐ ์ค์ผ๋ ์ ์์
- ์ญํ
- CPython ์์ฒด์ CPython์ด ์ฌ์ฉํ๋ C ํ์ฅ ๋ชจ๋์ด ์คํ๋๋ฉด์ ์ธํฐ๋ฝํธ๊ฐ ํจ๋ถ๋ก ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์ง
- ์ธํฐํ๋ฆฌํฐ ์ํ๊ฐ ์ ๋๋ก ์ ์ง๋๊ณ ๋ฐ์ดํธ์ฝ๋ ๋ช ๋ น๋ค์ด ์ ๋๋ก ์คํ๋๋๋ก ๋ง๋ฌ
- side-effect
- python ๋ค์ค ์ค๋ ๋ ์ง์ํ์ง๋ง GIL๋ก ์ธํด ์ฌ๋ฌ ์ค๋ ๋ ์ค ์ด๋ ํ๋๋ง ์งํ ๊ฐ๋ฅ
- ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํํ๊ณ ์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์๋จ
- ์์ค ์ฝ๋๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํด์ ๋ฐ์ดํธ์ฝ๋๋ก ๋ณํ
-
์์ฐจ์ ์คํ ์์
import time def factorize(number): for i in range(1, number + 1): if number % i == 0: yield i numbers = [2139079, 1214759, 1516637, 1852285] start = time.time() for number in numbers: list(factorize(number)) end = time.time() delta = end - start print(f'์ด {delta:.3f} ์ด ๊ฑธ๋ฆผ') >>> ์ด 0.256 ์ด ๊ฑธ๋ฆผ
-
์ค๋ ๋๋ฅผ ์ฌ์ฉํ ์์
from threading import Thread class FactorizeThread(Thread): def __init__(self, number): super().__init__() self.number = number def run(self): self.factors = list(factorize(self.number)) start = time.time() threads = [] for number in numbers: thread = FactorizeThread(number) thread.start() threads.append(thread) for thread in threads: thread.join() end = time.time() delta = end - start print(f'์ด {delta:.3f} ์ด ๊ฑธ๋ฆผ') >>> ์ด 0.446 ์ด ๊ฑธ๋ฆผ
-
์์ฐจ์ ์คํ๋ณด๋ค ์ค๋ ๋ ์คํ์ด ๋ ์ค๋ ๊ฑธ๋ฆผ
- ํด๋น ์์ ์์๋ 9900k ์์ WSL ์ํ์์ ์คํํ ๊ฒฐ๊ณผ ๊ทผ์ํ๊ฒ ์ค๋ ๋ ์ฌ์ฉ ์์ ์ ์๊ฐ์ด ๋ ๋นจ๋์ผ๋ ๊ฒฐ๊ตญ ์ฑ๋ฅํฅ์์ ์๋ค๊ณ ๊ฐ์กฐํจ
- ๋ค๋ฅธ ์ธ์ด์ ๋นํด ์ค๋ ๋๋ฅผ ํ๋์ฉ ํ ๋นํ๋ฉด, ์ค๋ ๋ ์์ฑ ๋ฐ ์กฐ์ ์ ๋ฐ๋ฅธ ๋ถ๊ฐ ๋น์ฉ์ด ๋ฐ์
- ํด๋น ๊ฒฐ๊ณผ๋ ํ์ค CPython ์ธํฐํ๋ฆฌํฐ์์ GIL์ ๋ฝ ์ถฉ๋๊ณผ ์ค์ผ์ค๋ง ๋ถ๊ฐ ๋น์ฉ์ด ๋ฏธ์น๋ ์ํฅ์ ์ ๋ณด์ฌ์ฃผ๋ ์
-
๋ค์ค ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก๊ทธ๋จ์ ๋์์ ์ฌ๋ฌ ์ผ์ ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ๋ง๋ค๊ธฐ ์ฌ์
- ๋์์ฑ ์์ ์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ฉด GIL์ ์ํด ์ค๋ ๋ ์ค ํ๋๋ง ์คํ์ด ๋์ง๋ง CPython ์ด ์ด๋ ์ ๋ ๊ท ์ผํ๊ฒ ๊ฐ ์ค๋ ๋๋ฅผ ์คํ์ํค๋ฏ๋ก ๋ค์ค ์ค๋ ๋๋ฅผ ํตํด ์ฌ๋ฌ ํจ์๋ฅผ ๋์์ ์คํ ๊ฐ๋ฅ
-
๋ธ๋กํน I/O ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํจ
- python ์ด ํน์ system call ์ ์ฌ์ฉํ ๋ ๋ฐ์
- ํ์ผ read/write, network interaction, hardware ๊ฐ ํต์ ๊ณผ ๊ฐ์ ์์ ์ด ๋ธ๋กํน I/O ์ ์ํจ
- ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ด์์ฒด์ ๊ฐ system call ์์ฒญ์ ์๋ตํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ ๋์ ๋ค๋ฅธ ์์ ๊ฐ๋ฅ
-
์ง๋ ฌ ํฌํธ๋ฅผ ํตํด ์๊ฒฉ ์ ์ด ํฌ๋ฆฌ์ฝฅํฐ์ ์ ํธ๋ฅผ ๋ณด๋ด๋ ์์ฐจ์ ์คํ ์์
import select import socket def slow_systemcall(): select.select([socket.socket()], [], [], 0.1) start = time.time() for _ in range(5): slow_systemcall() end = time.time() delta = end - start print(f'์ด {delta:.3f} ์ด ๊ฑธ๋ฆผ') >>> ์ด 0.503 ์ด ๊ฑธ๋ฆผ
-
์ง๋ ฌ ํฌํธ๋ฅผ ํตํด ์๊ฒฉ ์ ์ด ํฌ๋ฆฌ์ฝฅํฐ์ ์ ํธ๋ฅผ ๋ณด๋ด๋ ์ค๋ ๋ ์คํ ์์
start = time.time() threads = [] for _ in range(5): thread = Thread(target=slow_systemcall) thread.start() threads.append(thread) def compute_helicopter_location(index): ... for i in range(5): compute_helicopter_location(i) for thread in threads: thread.join() end = time.time() delta = end - start print(f'์ด {delta:.3f} ์ด ๊ฑธ๋ฆผ') >>> ์ด 0.102 ์ด ๊ฑธ๋ฆผ
-
slow_systemcallํจ์๊ฐ ์คํ๋๋ ๋์ ํ๋ก๊ทธ๋จ์ ์๋ฌด๊ฒ๋ ์์ ์ ์งํํ์ง ๋ชปํจselect์์คํ ์ฝ์ ์ํด ๋ธ๋ก๋จ- ํฌ๋ฆฌ์ฝฅํฐ์ ์ ํธ๋ฅผ ๋ณด๋ด๋ ๋์ ํฌ๋ฆฌ์ฝฅํฐ๊ฐ ๋ค์์ ์ด๋๋ก ์ด๋ํ ์ง ๊ณ์ฐ ๊ฐ๋ฅํด์ผ ํ๋๋ฐ ์์ฐจ์ ์คํ์ ์ด๋ฐ ์์ ์ ๋์์ ํ์ง ๋ชปํจ
-
slow_systemcall์ ์ฌ๋ฌ ์ค๋ ๋์์ ๋ฐ๋ก ํธ์ถํ๋๋ก ํ์ฌ ๋ธ๋ก ์์ ๊ณผ python ์์ ์ ๋์์ ๊ฐ๋ฅํ๋๋ก ๊ตฌํ
- GIL๋ก ์ธํด ์๊ธฐ๋ ํ๊ณ๊ฐ ์๋๋ผ๋ ์ฌ๋ฌ ์ค๋ ๋๋ฅผ ํตํด ์์คํ ์ฝ์ ๋ณ๋ ฌ๋ก ์คํํ ์ ์์์ ๋ณด์ฌ์คฌ์
- ์ค๋ ๋ ์ธ์๋ asyncio ๋ด์ฅ ๋ชจ๋๊ณผ ๊ฐ์ด ๋ธ๋กํน I/O ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์กด์ฌ
- ๋์์ ์ฌ์ฉํ๋ ค๋ฉด ๊ฐ ์คํ ๋ชจ๋์ ๋ง๊ฒ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ ์ถ๊ฐ ์์ ์ด ํ์ํจ
- ์ฝ๋๋ฅผ ๊ฐ๊ธ์ ํฌ๊ฒ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ธ๋กํน I/O ๋ฅผ ๋ณ๋ ฌ๋ก ์คํํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐํธ