Cython
사이썬(Cython)은 CPython 확장 모듈을 손쉽게 생성하도록 고안된 컴파일 언어이다. 파이썬 문법을 기반으로 C/C++ 루틴을 호출을 위한 외부 함수 인터페이스와 실행 속도 향상을 위한 정적 형 지정 등이 추가된 형태를 하고 있다. 이러한 특징은 파이썬의 빠른 생산성을 유지하면서도 외부 C 라이브러리와 간결하게 연동하거나 실행 속도 향상 할 수 있도록 해준다.
Categories
- Recc:cython
Simple Example
우선 helloworld.pyx
파일로 아래와 같이 저장한다.
setup.py
파일을 만들고 아래와 같이 컴파일할 파일명을 입력한다.
from distutils.core import setup
from Cython.Build import cythonize
setup( ext_modules = cythonize("helloworld.pyx") )
아래와 같이 실행하면 동적 라이브러리가 만들어 진다.
실제 사용은 일반 Python과 같이 적용하면 된다.
More simple
아래와 같이 입력하면 *.c
파일이 생성된다. 이 파일을 gcc등으로 컴파일 하면 된다.
Flags
-
--embed
- 단일파일로 임베드한다? - 좀더 확인.
Source Files and Compilation
C-Flags
-
Stackoverflow - How to remove -pthread compiler flag from cython setup file- Python 3.7 에서 잘 작동하지 않았다.
Packaging
- Integrating Cython extension with setuptools and unit testing
- Stackoverflow - Package only binary compiled .so files of a python library compiled with Cython
- [추천] Cython 코드가 포함 된 Python 패키지를 어떻게 구성해야합니까
- Stackoverflow - How should I structure a Python package that contains Cython code
- [추천] Distributing python packages protected with Cython
setup.py설정 후 tox, devpi 등에서 일반적으로 배포시 사용하는 명령은 sdist
이다.
Single file compile
WARNING |
ChatGPT 답변 결과임. 확인 필요 |
extensions = [
Extension(
name="your_module", # 모듈 이름
sources=["module1.pyx", "module2.pyx", "module3.py"], # 파일들
extra_compile_args=["-O3"], # 컴파일러 최적화 플래그
extra_link_args=[] # 추가적인 링킹 플래그
)
]
setup(
ext_modules=cythonize(extensions)
)
Pure Python Benchmark
다음 test.py
코드를 Cython 버전과, Python 버전으로 돌렸을 때 성능차이를 확인했다.
import math
def test(a):
mean = sum(a) / len(a)
return math.sqrt((sum(((x - mean)**2 for x in a)) / len(a)))
Cython 모듈을 만들기 위한 setup.py
파일:
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("test.py")
)
컴파일은 다음과 같이 실행.
테스트 코드는 다음과 같다:
import datetime
import sys
from test import test as test1 # Cython method.
from test2 import test as test2 # Python method.
if __name__ == "__main__":
a = [i for i in range(100000000)]
now = datetime.datetime.now()
k = test1(a)
print("cython:", datetime.datetime.now() - now)
now = datetime.datetime.now()
k = test2(a)
print("python:", datetime.datetime.now() - now)
exit(0)
성능 차이는 다음과 같다:
1억번 루프를 돌렸을 경우 5초 차이로 Cython 승!
Troubleshooting
FutureWarning language_level not set
language_level
을 설정한다. *.pyx
파일 첫 줄에 다음 주석을 추가하면 된다.
Customize location of .so file generated by Cython
setup.py를 다음과 같이 적용한다.
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext
ext_modules=[
Extension("package.wrapper.wrap", # location of the resulting .so
["package/wrapper/wrap.pyx"],) ]
setup(name='package',
packages=find_packages(),
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
)
그리고 다음과 같이 컴파일한다.
cython 파일을 setup.py 에 위치시키는 방법
Resolved through corrected MANIFEST.in:
MANIFEST.in and setup.py must both cover all file patterns to support bdist
and sdist
.
error: each element of 'ext_modules' option must be an Extension instance or 2-tuple
- Stackoverflow - error: each element of 'ext_modules' option must be an Extension instance or 2-tuple
Cython 패키지를 포함시킬 때 setuptools보다 먼저 추가되면 안된다:
# from Cython.Build import cythonize # BED CODE !!!!
from setuptools import find_packages, setup
from setuptools.command.build_py import build_py
from Cython.Build import cythonize # Correct CODE !!!!
See also
Favorite site
- Cython web site
- Wikipedia (en) Cython
- Using PyInstaller and Cython to create a Python executable | peterspython.com - 두 개의 변수에 대한 정적 Cython 유형 선언을 추가했더니 성능이 50배 향상되었습니다.