[Cython] 싸이썬, 파이썬에 속도를 더하다 Develop Tip

얼마전 페이스북에서 하나의 블로그 내용을 보았습니다.

파이썬을 짜면서 가장 걸리는 부분이 속도 문제인데 이를 해결하기 위하여
프로파일링 등을 통한 시간이 오래 걸리는 함수들을 C로 포팅하여 CTypes 등으로 
해결하고는 했습니다.

그런데 만약 뭔가 위에처럼 좋은게 있다면 얼마나 좋을까 하는 생각 들어서 살펴보았습니다.

Cython 홈페이지를 들어가 보았습니다.

C 확장이라는 이야기가 나오는군요. 또한 Pyrex에서 출발했다고도 나옵니다.

Pyrex를 위키피디어에서 찾았더니,

앗! 파이렉스 유리용기가 나오는데, 이게 아니구 첫번째에 있는 Pyrex(Programming Language)를 눌렀더니,

음... 뭔가 파이썬 속도를 빠르게 하기위하여 Python-like 한 것이 C와 관련이 있나보다...싶네요.

암튼 설치부터 간단 테스트 까지 진행해 보았습니다.

설치는 최신 버전의 pip가 있다면, (우분투12.04에서는 다음 참조
한줄로 설치 가능합니다.

$ sudo pip install cython

위와 같이 설치되고,

$ pip list
Cython (0.19.2)
...

위와 같이 설치되었음을 알 수 있습니다.

간단히 홈페이지에 있는 다큐먼트에 따라
작업을 해 보았습니다.

$ cat cytest.pyx

cdef extern from "math.h":
double sin(double)

cdef double f(double x) except *:
return sin(x**2)

def integrate(double a, double b, int N):
cdef int i
cdef double dx, s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s*dx

일반 파이썬 함수 및 언어와 거의 동일한데
대신 C와 같이 변수 선언 (cdef int) 부분만 틀리네요.

함수는 sin 함수를 이용한 interate를 구하는 함수를 구현해 놓았습니다.
확장자는 pyx 라고 하였습니다.

cython 이라는 실행파일이 뭐지 하고 그냥 돌려보았습니다.

$ cython cytest.pyx
이랬더니, cytest.c 
라는 파일이 만들어졌습니다.

아하!! pyx라는 것은 파이썬과 가장 유사한 문법으로
코딩을 하면 그것을 순수 C로 소스 차원에서 변환해 주어
Python에서 그대로 이용할 수 있게 만드는 것이군요!!!
라는 감이 딱 왔습니다.

그런데 더 쉽게 모듈을 build 할 수 있는 방법이 있으니, 

$ cat setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(
  name = 'cytest app',
  ext_modules = cythonize("cytest.pyx"),
)

라는 식으로 setup.py를 만들어 줍니다.

또한 다음과 같이 실행하면,

$ python setup.py build_ext --inplace
cytest.so 결과가 만들어 집니다.

이제 그냥 python 코드를 cytest2 라고 만들어 보았습니다.

$ cat setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(
  name = 'cytest app',
  ext_modules = cythonize("cytest.pyx"),
)
toor@UCMC:~/tmp/cython$ 
toor@UCMC:~/tmp/cython$ 
toor@UCMC:~/tmp/cython$ cat cytest2.py

import math

def f(x):
return math.sin(x**2)

def integrate(a, b, N):
s = 0.0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s*dx

그리고 마지막으로,
cython으로 만들어진 모듈의 함수와
파이썬으로 만들어진 모듈의 함수를
호출하여 몇배 빠른가 실행해 보았습니다.

$ cat cymain.py 
import datetime
import cytest
import cytest2

a=0.0234
b=0.1234
N=10000000

sts = datetime.datetime.now()
r = cytest.integrate(a,b,N)
ets = datetime.datetime.now()
t1diff = ets - sts
print "cytest.integrate(a=%f, b=%f, N=%d) = %f takes %s" % (a,b,N,r, t1diff)

sts = datetime.datetime.now()
r = cytest2.integrate(a,b,N)
ets = datetime.datetime.now()
t2diff = ets - sts
print "cytest2.integrate(a=%f, b=%f, N=%d) = %f takes %s" % (a,b,N,r, t2diff)

times = t2diff.total_seconds() / t1diff.total_seconds()
print "cytest is faster than cytest2 %d times" % int(times)

그리고 돌려보았더니,...

$ python cymain.py 
cytest.integrate(a=0.023400, b=0.123400, N=10000000) = 0.000622 takes 0:00:00.318338
cytest2.integrate(a=0.023400, b=0.123400, N=10000000) = 0.000622 takes 0:00:04.816900
cytest is faster than cytest2 15 times

뭐 이 결과만을 놓고보면 천만번 루프를 도는데 15배 빠르군요.

경우에 따라 백배가 빠를 수도 있겠지요?


어느 분께는 도움이 되셨기를...



핑백

덧글

  • ds 2016/01/15 00:03 # 삭제 답글

    와! 감사합니다! 파이썬으로 돌리는데 단순해서 좋지만 너무 느려서 힘들더군요.. 다시 C로 돌아갈까 했지만 파이썬의 단순함에 빠져서 방법이 없나 찾고 있었는데 완전 좋은 팁 얻고 가네요!!
  • 지훈현서아빠 2016/01/15 07:44 #

    실제 loop 등을 돌려보면 pypy가 더 빠른 경우도 있었습니다.
    참고하십시오. ^^
  • Dane 2017/10/08 20:32 # 삭제 답글

    Pypy 이외에도, Numba 쓰는것도 고려해보시면 좋아요^^ 간단한 함수는 Numba 로 돌리면 엄청 빠르게 작성하고(한줄만 추가하면됨) 스피드도 Cython 하고 비슷하게 나오더군요.
  • 지훈현서아빠 2017/10/08 22:14 #

    좋은 정보 감사드립니다~ ^^
  • soo 2018/02/02 15:22 # 삭제 답글

    정말 흥미롭네요^^
    윈도우에서는 어떻게 cython을 try해볼 수 있을 까요? 또는 참조 site.
    감사합니다.
  • 지훈현서아빠 2018/02/04 12:09 #

    https://github.com/cython/cython/wiki/InstallingOnWindows
    참고하시거나,
    http://mcchae.egloos.com/11152022
    보시고 pypy를 이용해 보시는 것도 좋을 듯...
    도움이 되셨기를 바랍니다.
  • 공부 2018/02/12 22:24 # 삭제 답글

    개발자로 진로를 잡고 공부해보려고 하는데 자바 파이썬중에서 고민이 됩니다. 미국은 파이썬이 대세라고 하더라구요 근데 파이썬보다 사이썬이 더 유용하다면 사이썬을 배우는게 낫지않나요? 근데 사이썬은 정보가 거의없고 학원도 없네요.. 어느 언어를 배워야할까요?
  • 지훈현서아빠 2018/02/13 15:26 #

    Cython 은 고민하지 마시구요, 일단 파이썬을 배우고 적용해서 자신의 언어로 이용하시는 것이 좋을 듯 합니다.
    나중에 속도가 문제되는 경우에만 해당 부분을 살짝 수정하면 됩니다.
    도움이 되셨기를... ^^
  • Dane 2018/05/31 14:07 # 삭제

    Python 공부하시다가, 어느정도 지식이쌓이고 성능개선이 필요하다싶은 시점이 오시면 "고성능 파이썬" 책 한번보시면 좋을듯합니다^^
  • dd 2018/12/06 01:00 # 삭제 답글

    유리그릇에서 피식 했네요 글 잘 읽었어요
댓글 입력 영역

구글애드텍스트