ABOUT ME

-

Total
-
  • Cython을 이용한 Bubble Sort
    컴퓨터/파이썬 2020. 10. 24. 19:43
    728x90
    반응형

    문법

    1. bint 타입으로 bool을 이용할 수 있음.

    cdef bint swapped = False

     

    2. len(array)는 Py_ssize_t를 return함.

      // C에서 len(array) - 1 을 구하는 과정
      if (unlikely(__pyx_v_array == Py_None)) {
        PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
        __PYX_ERR(0, 10, __pyx_L1_error)
      }
      __pyx_t_1 = PyList_GET_SIZE(__pyx_v_array); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 10, __pyx_L1_error)
      __pyx_v_n = (__pyx_t_1 - 1);

     

    3. cdef int, cdef double..., c타입 지정은 cdef 타입을 사용하면 됨.

    cdef int a = 0
    cdef double b = 0
    cdef bint booltype = True
    cdef Py_ssize_t i
    
    
    ctypedef fused A:
        int
        long
    
    ctypedef fused B:
        int
        long
    
    # int나 long array
    def myfunc(A[:] a, B[:] b):
        pass
        
        
    # built-in fused type
    cython.integral # short, int, long
    cython.floating # float, double
    cython.numeric  # short, int, long, float, double, float complex, double complex

     

    4. for문 아래 두 방법으로 쓰일 수 있는데 결과는 같음.

    # Cython
    for i from 0 <= i < n - count by 2:
        print(i)
        
    # Python
    for i in range(0, n - count, 2):
        print(i)
    // 생성되는 C 코드
    __pyx_t_1 = PyList_GET_SIZE(__pyx_v_array); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 10, __pyx_L1_error)
      __pyx_v_n = (__pyx_t_1 - 1);  // n = len(array) - 1
    __pyx_v_count = 0;  // count = 0
    
    __pyx_t_1 = (__pyx_v_n - __pyx_v_count);  // n - count
    
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++)

     

    5. Fused Type: 한 변수가 float 이나 int를 사용하고 싶은 경우

    struct를 이용한 상태를 이용하면 됨.

    공식 문서 링크: cython.readthedocs.io/en/latest/src/userguide/fusedtypes.html

    ctypedef fused char_or_float:
        char
        float
    
    
    cpdef char_or_float plus_one(char_or_float var):
        return var + 1
    
    
    def show_me():
        cdef:
            char a = 127
            float b = 127
        print('char', plus_one(a))
        print('float', plus_one(b))

     

    소스

    def bubbleSort(list array):
        return bubbleSort_c(array)
    
    cdef bubbleSort_c(list array):
        cdef bint isSorted = False
        cdef int count = 0
        cdef Py_ssize_t i
        cdef Py_ssize_t n = len(array) - 1
    
        while not isSorted:
            isSorted = True
            for i from 0 <= i < n - count:
                if array[i] > array[i + 1]:
                    array[i], array[i + 1] = array[i + 1], array[i]
                    isSorted = False
    
            count += 1
    
        return array

     

    결과

    Running cython_bubbleSort(tests) vs python_bubbleSort(tests)
    cython_bubbleSort is 787.1% faster than python_bubbleSort on 8 of 9 cases
    
    # 약 800% 가량 빠르다.

     

    아래 command로 C를 이용하는 지, 파이썬을 참고하는지 볼 수 있음.

    cython -a my_py.py

     

    728x90

    댓글