2021. 7. 28. 22:24ㆍ개발/Python
Python 은 언어의 특성상 C언어 같이 컴파일하는 언어에 비해 느리다.
그래서 실행 속도를 개선하고자하는 움직임이 많이 있었는데, 아무래도 C언어와 가장 유사한 성능을 보여주기 위해서는 Cython 사용이 필요하다고 판단했다.
자료를 조금 찾아보니 Python을 사용하는 모든 곳에 적합한 것을 아니고, 연산이 많은 앱에 특화되어있었다. 왜냐하면, Python은 C언어처럼 변수 선언시 자료형을 쓰지 않기때문에 runtime중 type 을 참고하는데 은근 많은 시간을 소비한다고 한다. (Django 같은 web framework 에서는 굳이 쓸필요가 없다. 쓰면 아주 조금의 성능 개선은 있겠지만, 오히려 버그를 만들 수 있는 요인이 되기도 한다. 소탐대실할 수 있다.)
Cython 사용법
cython 모듈을 설치한다.
pip install cython
build script를 작성한다. (원하는 py파일을 모두 넣어주면 된다.)
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("main.py")
)
build를 돌린다. (돌리면, pyd파일과 c파일 2개가 생성된다. 이는 C언어로 브릿징 시켜주는 파일이다.)
python build_script.py build_ext --inplace
그리고 main을 실행하면 브릿징된 C언어로 동작하게 된다.
그래서 단순반복적인 일을 시켜 얼마만큼의 성능 개선이 있는지 확인해보았다.
Test Code
#### main.py
import timeit
from run import run
from run2 import run2
if __name__ == '__main__':
start_time = timeit.default_timer()
run.run()
print("RUN Time : " + str(timeit.default_timer() - start_time))
start_time = timeit.default_timer()
run2.run()
print("RUN2 Time : " + str(timeit.default_timer() - start_time))
#### run.py
class run:
@staticmethod
def run():
for i in range(100000000):
if isinstance('a', list):
pass
#### run2.py
class run2:
@staticmethod
def run():
for i in range(100000000):
if isinstance('a', list):
pass
테스트 파일 3개를 만들고, run.py만 cython으로 변환시켜주었다.
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("run.py")
)
출력을 보니 생각보다 훨씬 빨랐다.
RUN Time : 3.600000000006376e-06
RUN2 Time : 20.9462649
cython 사용시 3.6 * 10^-6 초인 반면 순수 python에서는 20초나 걸렸다.
너무 단순하고 파이썬에 불리한 코드여서 발생했을 수 있지만, python에 비해 확실히 성능 향상을 있었음을 확인할 수 있었다.