Cython은 무엇입니까? C 속도의 Python

Python은 가장 편리하고 풍부한 장비를 갖춘 매우 유용한 프로그래밍 언어 중 하나로 명성이 높습니다. 실행 속도? 별로.

Cython을 입력하십시오. Cython 언어는 C로 컴파일되는 Python의 상위 집합으로, 수행중인 작업에 따라 몇 퍼센트에서 몇 배까지 성능이 향상 될 수 있습니다. Python의 기본 객체 유형에 묶여있는 작업의 경우 속도 향상이 크지 않습니다. 그러나 수치 연산이나 파이썬 자체 내부를 포함하지 않는 연산의 경우 엄청난 이득이있을 수 있습니다. 

Cython을 사용하면 Python의 편리함과 편리함을 포기하지 않고도 Python의 많은 기본 제한을 무시하거나 완전히 초월 할 수 있습니다. 이 기사에서는 Cython의 기본 개념을 살펴보고 Cython을 사용하여 기능 중 하나를 가속화하는 간단한 Python 애플리케이션을 만듭니다.

관련 비디오 : Cython을 사용하여 Python 속도 향상

Python을 C로 컴파일

Python 코드는 C 모듈을 직접 호출 할 수 있습니다. 이러한 C 모듈은 일반 C 라이브러리이거나 Python과 함께 작동하도록 특별히 빌드 된 라이브러리 일 수 있습니다. Cython은 두 번째 종류의 모듈을 생성합니다 : Python의 내부와 통신하고 기존 Python 코드와 함께 번들로 제공 할 수있는 C 라이브러리입니다.

Cython 코드는 설계 상 Python 코드와 매우 유사합니다. Cython 컴파일러에 Python 프로그램을 제공하면 (Python 2.x 및 Python 3.x가 모두 지원됨) Cython은 그대로 받아들이지 만 Cython의 기본 가속 기능은 작동하지 않습니다. 그러나 Cython의 특수 구문에서 유형 주석으로 Python 코드를 장식하면 Cython은 느린 Python 객체를 빠른 C 등가물로 대체 할 수 있습니다.

Cython의 접근 방식은  점진적 입니다. 즉, 개발자는 전체 애플리케이션을 처음부터 다시 작성하는 대신 기존 Python 애플리케이션으로 시작  하여 코드를 부분적으로 변경하여 속도를 높일 수 있습니다.

이 접근 방식은 일반적으로 소프트웨어 성능 문제의 특성과 관련이 있습니다. 대부분의 프로그램에서 대부분의 CPU 집약적 코드는 "80/20"규칙이라고도하는 Pareto 원칙의 버전 인 몇 가지 핫스팟에 집중되어 있습니다. 따라서 Python 애플리케이션에있는 대부분의 코드는 성능 최적화가 필요하지 않고 몇 가지 중요한 부분 만 있으면됩니다. 이러한 핫스팟을 Cython으로 점진적으로 변환 할 수 있으므로 가장 중요한 곳에서 필요한 성능 향상을 얻을 수 있습니다. 나머지 프로그램은 개발자의 편의를 위해 Python에 남아있을 수 있습니다.

Cython 사용 방법

Cython의 문서에서 가져온 다음 코드를 고려하십시오.

정의 f (x) :

    x ** 2-x 반환

def integration_f (a, b, N) :

    s = 0

    dx = (ba) / N

    범위 (N)에있는 i의 경우 :

        s + = f (a + i * dx)

    s * dx 반환

이것은 적분 함수의 비효율적 인 구현 인 장난감 예제입니다. 순수한 Python 코드로서 Python은 기계 고유의 숫자 유형과 자체 내부 객체 유형간에 앞뒤로 변환해야하므로 느립니다.

이제 Cython의 추가 사항이 강조 표시된 동일한 코드의 Cython 버전을 고려하십시오.

 cdef double f (double x) :

    x ** 2-x 반환

def integration_f (double a, double b, int N) :

    cdef int i

    cdef double s, x, dx

    s = 0

    dx = (ba) / N

    범위 (N)에있는 i의 경우 :

        s + = f (a + i * dx)

    s * dx 반환

우리가 명시 적으로 변수 유형을 선언 할 경우, 함수 (본문에 사용 된 함수 매개 변수와 변수 모두 double, int등) 사이 썬 우리는 또한 사용할 수 있습니다 C.에이 모든 것을 번역 할 cdef수 있습니다 함수를 정의하는 키워드를 추가 속도를 위해 주로 C로 구현되지만 이러한 함수는 Python 스크립트가 아닌 다른 Cython 함수에 의해서만 호출 될 수 있습니다. (위의 예에서는 integrate_f다른 Python 스크립트 에서만 호출 할 수 있습니다.)

실제 코드 가 얼마나 변경 되었는지 주목하십시오  . 우리가 한 것은 상당한 성능 향상을 위해 기존 코드에 유형 선언을 추가하는 것입니다.

Cython의 장점

이미 작성한 코드의 속도를 높일 수있는 것 외에도 Cython은 몇 가지 다른 이점을 제공합니다.

외부 C 라이브러리로 작업하는 것이 더 빨라질 수 있습니다.

NumPy와 같은 Python 패키지는 C 라이브러리를 Python 인터페이스로 래핑하여 작업하기 쉽습니다. 그러나 이러한 래퍼를 통해 Python과 C간에 앞뒤로 이동하면 속도가 느려질 수 있습니다. Cython을 사용하면 Python 없이도 기본 라이브러리와 직접 통신 할 수 있습니다. (C ++ 라이브러리도 지원됩니다.)

C 및 Python 메모리 관리를 모두 사용할 수 있습니다.

Python 객체를 사용하는 경우 일반 Python과 동일하게 메모리 관리 및 가비지 수집됩니다. 그러나 자신의 C 레벨 구조를 만들고 관리하고 malloc/ free를 사용 하여 작업하려면 그렇게 할 수 있습니다. 스스로 청소하는 것을 잊지 마십시오.

필요에 따라 안전 또는 속도를 선택할 수 있습니다. 

Cython은 데코레이터 및 컴파일러 지시문 (예 :)을 통해 배열에 대한 경계를 벗어난 액세스와 같이 C에서 나타나는 일반적인 문제에 대해 런타임 검사를 자동으로 수행합니다 @boundscheck(False). 결과적으로 Cython에 의해 생성 된 C 코드는 기본적으로 수동 C 코드보다 훨씬 안전하지만 잠재적으로 원시 성능을 희생 할 수 있습니다.

런타임에 이러한 검사가 필요하지 않다고 확신하는 경우 전체 모듈에서 또는 일부 기능에서만 추가 속도 향상을 위해 비활성화 할 수 있습니다.

Cython을 사용하면 메모리에 저장된 데이터에 직접 액세스하기 위해 버퍼 프로토콜을 사용하는 Python 구조에 기본적으로 액세스 할 수 있습니다 (중간 복사없이). Cython의 메모리 뷰를 사용하면 이러한 구조를 작업에 적합한 안전 수준으로 고속으로 작업 할 수 있습니다. 예를 들어, Python 문자열의 기초가되는 원시 데이터는 Python 런타임 (느리게)을 거치지 않고도 이러한 방식으로 (빠르게) 읽을 수 있습니다.

Cython C 코드는 GIL을 릴리스하여 혜택을 볼 수 있습니다.

Python의 Global Interpreter Lock (GIL)은 인터프리터 내의 스레드를 동기화하여 Python 객체에 대한 액세스를 보호하고 리소스에 대한 경합을 관리합니다. 그러나 GIL은 특히 멀티 코어 시스템에서 더 나은 성능의 Python의 걸림돌로 널리 비판을 받아 왔습니다.

Python 객체를 참조하지 않고 장기 실행 작업을 수행하는 코드 섹션이있는 경우 with nogil:GIL없이 실행할 수 있도록 지시문으로 표시 할 수 있습니다  . 이렇게하면 Python 인터프리터가 다른 작업을 수행 할 수 있고 Cython 코드가 여러 코어를 사용할 수 있습니다 (추가 작업 포함).

Cython은 Python 유형 힌팅 구문을 사용할 수 있습니다. 

Python에는 CPython 인터프리터가 아니라 주로 린터 및 코드 검사기에서 사용하는 유형 힌트 구문이 있습니다. Cython에는 코드 장식을위한 자체 사용자 지정 구문이 있지만 최근 Cython 개정에서는 Python 유형 힌트 구문을 사용하여 Cython에 기본 유형 힌트도 제공 할 수 있습니다. 

Cython을 사용하여 민감한 Python 코드를 가릴 수 있습니다.

파이썬 모듈은 디 컴파일하고 검사하기가 쉽지만 컴파일 된 바이너리는 그렇지 않습니다. Python 애플리케이션을 최종 사용자에게 배포 할 때 일부 모듈을 일시적인 스누핑으로부터 보호하려면 Cython으로 컴파일하면됩니다. 그러나 이것은 의도 된 기능 중 하나가 아니라 Cython 기능의 부작용 입니다.

Cython 제한

Cython은 마술 지팡이가 아닙니다. 모든 파이썬 코드 인스턴스를 지글 지글하고 빠른 C 코드로 자동 전환하지는 않습니다. Cython을 최대한 활용하려면이를 현명하게 사용하고 제한 사항을 이해해야합니다.

기존 Python 코드에 대한 약간의 속도 향상

Cython이 Python 코드를 만나면 완전히 C로 변환 할 수 없으며 해당 코드를 Python 내부에 대한 일련의 C 호출로 변환합니다. 이는 Python의 인터프리터를 실행 루프에서 제거하는 것과 같아서 기본적으로 코드 속도가 15 ~ 20 % 향상됩니다. 이것은 최상의 시나리오입니다. 어떤 상황에서는 성능이 향상되지 않거나 성능이 저하 될 수도 있습니다.

네이티브 Python 데이터 구조에 대한 약간의 속도 향상

Python은 문자열, 목록, 튜플, 사전 등 다양한 데이터 구조를 제공합니다. 개발자에게 매우 편리하며 자체 자동 메모리 관리 기능이 함께 제공됩니다. 그러나 그들은 순수한 C보다 느립니다.

Cython을 사용하면 속도 향상 없이도 모든 Python 데이터 구조를 계속 사용할 수 있습니다. 이것은 Cython이 단순히 Python 런타임에서 해당 객체를 만들고 조작하는 C API를 호출하기 때문입니다. 따라서 Python 데이터 구조는 일반적으로 Cython에 최적화 된 Python 코드와 매우 유사하게 작동합니다. 때때로 향상을 얻을 수 있지만 약간만 얻을 수 있습니다. 최상의 결과를 얻으려면 C 변수와 구조를 사용하십시오. 좋은 소식은 Cython이 그들과 쉽게 작업 할 수 있도록한다는 것입니다.

Cython 코드는 "순수 C"일 때 가장 빠르게 실행됩니다.

cdef모든 변수와 순수 C 인 다른 것에 대한 인라인 함수 호출 이 포함 된 키워드로 레이블이 지정된 C의 함수가 있으면 C가 가능한 한 빨리 실행됩니다. 그러나 해당 함수가 Python 데이터 구조 또는 내부 Python API에 대한 호출과 같은 Python 네이티브 코드를 참조하는 경우 해당 호출은 성능 병목 현상이됩니다.

다행히 Cython은 이러한 병목 현상을 발견 할 수있는 방법을 제공합니다. Cython 앱의 어떤 부분이 순수 C이고 어떤 부분이 Python과 상호 작용하는지 한 눈에 보여주는 소스 코드 보고서입니다. 앱을 더 잘 최적화할수록 Python과의 상호 작용이 줄어 듭니다.

Cython NumPy 

Cython은 NumPy와 같은 C 기반 타사 번호 처리 라이브러리의 사용을 개선합니다. Cython 코드는 C로 컴파일되기 때문에 해당 라이브러리와 직접 상호 작용할 수 있으며 Python의 병목 현상을 루프에서 제거 할 수 있습니다.

그러나 NumPy는 특히 Cython과 잘 작동합니다. Cython은 NumPy의 특정 구성을 기본적으로 지원하며 NumPy 배열에 대한 빠른 액세스를 제공합니다. 그리고 기존 Python 스크립트에서 사용하는 것과 동일한 익숙한 NumPy 구문을 Cython에서 그대로 사용할 수 있습니다.

그러나 Cython과 NumPy간에 가능한 가장 가까운 바인딩을 생성하려면 Cython의 사용자 정의 구문으로 코드를 추가로 장식해야합니다. cimport예를 들어, 이  명령문은 가능한 가장 빠른 바인딩을 위해 컴파일 타임에 Cython 코드가 라이브러리의 C 레벨 구문을 볼 수 있도록합니다.

NumPy가 널리 사용되기 때문에 Cython은 NumPy를 "즉시"지원합니다. NumPy가 설치되어있는 경우 cimport numpy 코드에 상태 를 지정한 다음 노출 된 함수를 사용하도록 장식을 추가 할 수 있습니다  . 

Cython 프로파일 링 및 성능

코드를 프로파일 링하고 병목 지점이있는 곳을 직접 확인함으로써 모든 코드에서 최고의 성능을 얻을 수 있습니다. Cython은 Python의 cProfile 모듈에 대한 후크를 제공하므로 cProfile과 같은 Python 고유의 프로파일 링 도구를 사용하여 Cython 코드의 성능을 확인할 수 있습니다. 

모든 경우에 Cython이 마술이 아니라는 사실을 기억하는 것이 좋습니다. 현명한 실제 성능 관행은 여전히 ​​적용됩니다. Python과 Cython 사이를 왕복하는 횟수가 적을수록 앱이 더 빠르게 실행됩니다.

예를 들어 Cython에서 처리하려는 객체 모음이있는 경우 Python에서 반복하지 말고 각 단계에서 Cython 함수를 호출하십시오. 패스 전체 컬렉션을 거기 사이 썬 모듈과 반복. 이 기술은 데이터를 관리하는 라이브러리에서 자주 사용되므로 자신의 코드에서 에뮬레이트하기에 좋은 모델입니다.

프로그래머의 편의를 제공하고 빠른 개발이 가능하기 때문에 Python을 사용합니다. 때때로 그 프로그래머의 생산성은 성능 저하를 가져옵니다. Cython을 사용하면 약간의 추가 노력만으로 두 세계의 장점을 모두 누릴 수 있습니다.

Python에 대해 자세히 알아보기

  • 파이썬이란 무엇입니까? 강력하고 직관적 인 프로그래밍
  • PyPy는 무엇입니까? 고통없는 더 빠른 Python
  • Cython은 무엇입니까? C 속도의 Python
  • Cython 튜토리얼 : 파이썬 속도를 높이는 방법
  • Python을 현명하게 설치하는 방법
  • Python 3.8의 가장 새로운 기능
  • Poetry로 더 나은 Python 프로젝트 관리
  • Virtualenv 및 Venv : Python 가상 환경 설명
  • Python virtualenv 및 venv해야 할 일과하지 말아야 할 일
  • Python 스레딩 및 하위 프로세스 설명
  • Python 디버거를 사용하는 방법
  • timeit을 사용하여 Python 코드를 프로파일 링하는 방법
  • cProfile을 사용하여 Python 코드를 프로파일 링하는 방법
  • Python에서 비동기 시작하기
  • Python에서 asyncio를 사용하는 방법
  • Python을 JavaScript로 변환하는 방법 (그리고 다시)
  • Python 2 EOL : Python 2의 끝에서 살아남는 방법
  • 모든 프로그래밍 요구를위한 12 개의 Python
  • 모든 Python 개발자를위한 24 개의 Python 라이브러리
  • 놓쳤을 수도있는 7 가지 멋진 Python IDE
  • Python의 3 가지 주요 단점 및 솔루션
  • 13 개의 Python 웹 프레임 워크 비교
  • 버그를 제거하는 4 가지 Python 테스트 프레임 워크
  • 놓치고 싶지 않은 6 가지 새로운 Python 기능
  • 기계 학습 마스터를위한 5 가지 Python 배포
  • 자연어 처리를위한 8 가지 훌륭한 Python 라이브러리