화요일, 4월 23, 2024
Home자동화'편리한' Python과 '빠른' Rust를 결합하는 방법

‘편리한’ Python과 ‘빠른’ Rust를 결합하는 방법


두 언어의 라이브러리 덕분에 Python의 ‘편리함’과 Rust의 ‘속도’를 결합하는 것이 가능합니다. PyO3 프로젝트와 CPython 크레이트부터 시작하겠습니다.

언뜻 보기에 Python과 Rust는 언어 스펙트럼의 반대쪽 끝을 차지합니다. 런타임으로 설명되는 Python은 개발자에게 유연하고 편리한 프로그래밍 환경을 제공하지만 실행 성능이 저하됩니다. Rust는 속도와 메모리 안정성을 제공하지만 메모리 작업을 처리하기 위한 새로운 패러다임을 배워야 합니다.

이론적으로 이러한 언어는 경쟁해서는 안 됩니다. 우리는 협력해야 합니다. 그리고 실제로 가능합니다. Rust는 Python의 사용 용이성이라는 이점을 누릴 수 있고, Python은 Rust의 속도와 안정성의 이점을 누릴 수 있습니다.

그러나 Rust를 Python과 함께 사용하거나 그 반대로 사용할 때 최적의 결과를 얻으려면 두 언어에 대한 최소한의 지식이 필요합니다. 또한 각 접근 방식에 대한 옵션이 크게 다르기 때문에 둘 중 어느 것이 기본 언어가 될지 결정해야 합니다.

ⓒ매튜 랭커스터(CC0)

PyO3를 사용하여 Python에서 Rust 호출하기
Python이 기본 언어인 경우 Rust와의 통합은 개념적으로 Python을 C와 통합하는 것과 동일한 방식으로 수행됩니다. C로 작성된 Python의 기본 구현은 C로 작성된 확장을 사용하거나 C 호환 ABI를 사용합니다. 동일한 API를 활용하는 Rust로 작성된 확장도 작동하지만 자동으로 작동하지는 않습니다. Python C API에 Rust 함수 바인딩을 제공하도록 설계된 크레이트를 사용해야 합니다.

Python에서 Rust 바인딩 만들기
Python에서 Rust 바인딩을 만드는 데 가장 인기 있는 프로젝트는 PyO3입니다. Rust로 Python 모듈을 작성하거나 Python 런타임을 Rust 바이너리에 포함하는 데 사용할 수 있습니다.

PyO3는 또 다른 프로젝트 ‘Maturin’을 활용합니다. 이것은 Python 패키징 및 바인딩을 사용하여 Rust 크레이트를 생성하는 도구입니다. Python 가상 환경에 설치되면 Matrin을 명령줄에서 사용하여 Python 바인딩이 활성화된 새 Rust 프로젝트를 초기화할 수 있습니다. 개발자는 Rust 코드에서 지시문을 사용하여 Python에 노출할 Rust 함수와 전체 Rust 프로젝트를 Python에 가져올 수 있는 모듈로 노출하는 방법을 나타낼 수 있습니다.

Rust와 Python 유형 매핑
PyO3의 유용한 기능 중 하나는 Rust와 Python 유형 간의 매핑입니다. Rust로 작성된 함수는 기본 Python 유형이나 Python 유형에서 변환된 Rust 유형을 사용할 수 있습니다. 예를 들어, 파이썬에서는 bytearray 또는 바이트 Rust의 객체 베크에 매핑될 수 있고 Python의 str은빛 녹 로 렌더링될 수 있습니다.

Python에서 Rust로 변환하면 호출당 비용이 발생하지만 Rust 코드에서 Python 유형을 완전히 사용할 필요가 없습니다. Cython에서 이는 C 유형으로 변환하는 것과 유사합니다. 각 변환에는 비용이 들지만 C에서의 수치 처리가 목표인 경우 상당한 속도 향상을 제공합니다.

CPython 크레이트를 사용하여 Rust에서 Python 호출하기
기본적으로 Rust 개발자이지만 Rust 애플리케이션 내에서 Python을 사용하고 싶다면 CPython Crate를 사용하는 간단한 방법이 있습니다. CPython 크레이트는 가장 일반적인 Python 런타임(C로 작성되었기 때문에 명명됨)인 CPython 인터프리터에 대한 Rust 바인딩을 제공합니다.

Rust 프로그램은 CPython 인터프리터를 호출하여 작동할 수 있으며, 이를 통해 Rust는 Python 객체를 생성 및 조작하고 라이브러리를 호출할 수 있습니다. 여기 Python 런타임을 초기화하고, 모듈을 가져오고, Python 개체를 만들고, 메서드 호출을 실행하는 방법을 보여주는 예제를 찾을 수 있습니다.

CPython 크레이트에는 유용한 매크로도 있습니다. 예를 들어 py_fn! 매크로는 Python에서 호출할 수 있도록 Rust 함수를 래핑합니다. py_class! 매크로를 사용하면 Rust 클래스를 Python 클래스 객체로 생성할 수 있습니다.

Python보다 Rust에 더 익숙하다면, 시작하기 전에 Python C API와 다양한 Python 객체 유형에 대해 어느 정도 친숙해지는 것이 좋습니다.

성능 팁
CPython과 PyO3 모두에서 중요한 주의 사항은 두 언어 간에 데이터를 교환하는 횟수를 항상 최소화해야 한다는 것입니다. Python에서 Rust로 또는 그 반대로 호출할 때마다 약간의 오버헤드가 발생합니다. 해당 오버헤드가 Rust가 수행하는 작업보다 크면 성능이 향상되지 않습니다.

예를 들어, 객체 컬렉션을 반복할 때 객체를 Rust로 보내고 루프를 수행합니다. 이는 Python 측에서 루프를 실행하고 루프가 반복될 때마다 Rust 코드를 호출하는 것보다 더 효율적입니다.

반면에 이러한 지침은 Python과 Python C ABI를 사용하는 다른 코드(예: Cython 모듈) 간의 통합에도 일반적으로 적용될 수 있습니다. ciokr@idg.co.kr



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments