개발자 / 오픈소스

‘편리한’ 파이썬과 ‘빠른’ 러스트를 결합하는 법

Serdar Yegulalp | InfoWorld 2022.07.08
라이브러리를 활용하면 파이썬(Python)의 ‘편리함’과 러스트(Rust)의 ‘속도’를 결합할 수 있다. 대표적으로 PyO3 프로젝트와 C파이썬(cpython)을 이용하면 된다. 

파이썬과 러스트는 서로 특징이 완전히 다른 언어처럼 보일 수 있다. 런타임 위에서 실행되는 파이썬은 개발자에게 유연하고 편리한 프로그래밍 환경을 제공하지만 실행 성능 측면에서는 아쉬운 점이 있다. 러스트는 속도와 메모리 안정성을 제공하지만 메모리 작업을 처리하는 과정에서 많은 수고가 필요하다. 

두 언어는 사실 경쟁하는 관계가 아니다. 대신 부족한 부분을 메꿔가면 동시에 사용할 수 있다. 러스트에 파이썬의 사용 편의성을, 파이썬에 러스트의 속도와 안정성을 더할 수 있는 셈이다. 

단, 두 언어의 장점을 통해 최적의 결과를 얻고 싶다면, 두 언어에 어느 정도 익숙해야 한다. 또 각 언어가 가진 철학이 많이 다르기 때문에, 둘 중 어느 것을 기본 언어로 설정할지 결정해야 한다. 
 
ⓒMatthew Lancaster (CC0)

PyO3로 파이썬에서 러스트 호출하기

파이썬이 기본 언어라면 러스트를 통합하는 과정은 개념적으로 파이썬을 C 언어와 통합하는 것과 동일한 방식으로 이뤄진다. C 언어로 작성된 파이썬의 기본 구현은 C 언어 또는 C와 호환되는 ABI에서 작성된 확장자를 쓴다. 러스트로 작성된 확장자도 동일한 ABI를 활용하기 자동으로 작동되는 것은 아니지만 비슷하게 진행된다. 이때 파이썬 C API에 러스트 함수 바인딩을 제공하도록 설계된 크레이트(Crate, 러스트용 코드 패키지)를 사용해야 한다. 

파이썬에서 러스트 바인딩 만들기

파이썬에서 러스트 바인딩을 생성할 때는 대표적으로 PyO3를 쓴다. 러스트에서 파이썬 모듈을 작성하거나 파이썬 런타임을 러스트 바이너리에 포함하는 데 사용할 수 있다. 

PyO3는 ‘마트린(Maturin)’을 활용한다. 이는 파이썬 패키징 및 바인딩으로 러스트 크레이트를 작성하는 도구다. 파이썬 가상 환경에 설치하면 마트린을 명령줄에서 사용하여 파이썬 바인딩이 활성화된 새 러스트 프로젝트를 초기화할 수 있다. 개발자는 러스트 코드에서 지시문을 사용하여 파이썬에 노출시킬 러스트 함수 그리고 러스트 프로젝트 전체를 파이썬에 가져올 수 있는 모듈로 노출하는 방법을 표시할 수 있다. 

러스트 및 파이썬 타입 매핑 

PyO3의 유용한 기능 중 하나는 러스트와 파이썬 타입 간의 매핑이다. 러스트로 작성된 함수는 네이티브 파이썬 타입 또는 파이썬 타입에서 변환된 러스트 타입을 모두 사용할 수 있다. 예를 들면 파이썬의 bytearray 또는 bytes 객체는 러스트의 Vec<u8>에 매핑될 수 있고, 파이썬의 str은 러스트 String으로 렌더링될 수 있다. 

파이썬에서 러스트로 변환하면 호출당 비용이 발생하지만 러스트 코드에서 파이썬 타입을 전적으로 사용할 필요가 없다. 사이썬에서 이는 C 타입으로의 변환과 비슷하다. 각 변환에는 비용이 들지만 만약 목표가 C에서의 수치 처리라면 상당한 속도 향상을 가져온다. 

C파이썬을 사용해 러스트에서 파이썬 호출하기 

러스트 개발자이지만 러스트 애플리케이션 내에서 파이썬을 사용하고 싶다면, C파이썬 크레이트를 이용하면 된다. C파이썬 크레이트는 가장 일반적인 파이썬 런타임인 C파이썬 인터프리터에 러스트 바인딩을 제공한다(C 언어로 작성됐기 때문에 앞에 C가 붙었다). 

러스트 프로그램은 C파이썬 인터프리터를 호출하여 작업할 수 있기 때문에 러스트에서 파이썬 객체를 만들고, 조작하며, 라이브러리를 호출할 수 있다. 이곳에서 라이썬 런타임을 초기화하고, 모듈을 가져오며, 파이썬 객체를 만들고, 메소드 호출을 실행하는 방법을 보여주는 예시를 확인할 수 있다. 

C파이썬 크레이트에는 몇 가지 유용한 매크로도 있다. 예를 들어 py_fn! 매크로는 파이썬에서 호출할 수 있도록 러스트 함수를 래핑한다. py_class! 매크로를 사용하면 러스트 클래스를 파이썬 클래스 객체로 생성할 수 있다. 

파이썬보다 러스트에 더 익숙하다면 이에 뛰어들기 전에 파이썬 C API와 다양한 파이썬 객체 유형에 최소한 어느 정도 알아 두는 게 좋다. 

성능 관련 팁 

C파이썬과 PyO3 모두에서 중요한 주의사항은 두 언어 간에 데이터를 주고받는 횟수를 항상 최소화해야 한다는 점이다. 파이썬에서 러스트로 또는 그 반대로 호출할 때마다 약간의 오버헤드가 발생한다. 해당 오버헤드가 러스트에서 수행하는 작업보다 크면 성능이 향상되지 않는다. 

예를 들어 객체 콜렉션에서 루프를 하는 경우 객체를 러스트로 보내고 루프를 수행한다. 이는 파이썬 측에서 루프를 실행하고 루프를 반복할 때마다 러스트 코드를 호출하는 것보다 더 효율적이다. 

한편 이 가이드라인은 파이썬과 사이썬 모듈처럼 파이썬 C ABI를 사용하는 다른 코드 간의 통합에도 일반적으로 적용될 수 있다.
ciokr@idg.co.kr
 

회사명 : 한국IDG | 제호: ITWorld | 주소 : 서울시 중구 세종대로 23, 4층 우)04512
| 등록번호 : 서울 아00743 등록발행일자 : 2009년 01월 19일

발행인 : 박형미 | 편집인 : 박재곤 | 청소년보호책임자 : 한정규
| 사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.