Nice programing

Python : SWIG 대 ctypes

nicepro 2020. 12. 31. 23:26
반응형

Python : SWIG 대 ctypes


파이썬에서는 어떤 상황에서 SWIG가 공유 라이브러리의 진입 점을 호출하는 데 ctypes보다 나은 선택입니까? SWIG 인터페이스 파일이 아직 없다고 가정합니다.

둘의 성능 메트릭은 무엇입니까?


SWIG는 C 또는 C ++ 코드를 생성합니다. 간단한 함수 (직접 번역 할 수있는 것)에 사용하는 것은 간단하고 더 복잡한 함수 (예 : Python에서 표현하기 위해 추가 번역 단계가 필요한 출력 매개 변수가있는 함수)에 사용하기 합리적으로 쉽습니다. 인터페이스 파일의 일부로 C 비트를 작성해야합니다. 단순한 사용을 제외하고는 CPython과 그것이 객체를 나타내는 방법에 대해 알아야합니다. 어렵지는 않지만 명심해야 할 사항입니다.

ctypes를 사용하면 C 함수, 구조 및 기타 데이터에 직접 액세스하고 임의의 공유 라이브러리를로드 할 수 있습니다. 이를 위해 C를 작성할 필요는 없지만 C가 어떻게 작동하는지 이해해야합니다. SWIG의이면이라고 할 수 있습니다. 코드를 생성하지 않고 런타임에 컴파일러가 필요하지 않습니다. 그러나 간단한 사용을 위해서는 C 데이터 유형, 캐스팅, 메모리 관리 및 정렬 작업. 또한 C 구조체, 공용체 및 배열을 올바른 메모리 레이아웃을 포함하여 동등한 ctypes 데이터 구조로 수동 또는 자동으로 변환해야합니다.

순수한 실행에서는 SWIG가 ctypes보다 빠를 가능성이 높습니다. 실제 작업에 대한 관리는 런타임에 Python이 아닌 컴파일 타임에 C로 수행되기 때문입니다. 그러나 서로 다른 많은 C 함수를 인터페이스하지 않고 각각 몇 번만 인터페이스하지 않으면 오버 헤드가 실제로 눈에 띄지 않을 것입니다.

개발 시간에 ctypes는 시작 비용이 훨씬 저렴합니다. 인터페이스 파일에 대해 배울 필요가없고 .c 파일을 생성하고 컴파일 할 필요가 없으며 경고를 확인하고 침묵시킬 필요가 없습니다. 최소한의 노력으로 시작하여 단일 C 함수를 사용한 다음 더 확장 할 수 있습니다. 그리고 Python 인터프리터에서 직접 테스트하고 시도해 볼 수 있습니다. 많은 코드를 래핑하는 것은 다소 지루하지만 (ctypes-configure와 같이) 더 간단하게 만들려는 시도가 있습니다.

반면에 SWIG는 여러 언어에 대한 래퍼를 생성하는 데 사용할 수 있습니다 (위에서 언급 한 사용자 지정 C 코드처럼 채워야하는 언어 별 세부 정보 제외). 또한 코드 생성은 ctypes에 해당하는 것보다 훨씬 간단하게 설정할 수 있습니다.


나는 swig를 사용한 풍부한 경험이 있습니다. SWIG는 포장을위한 신속한 솔루션이라고 주장합니다. 하지만 실생활에서는 ...


단점 :

SWIG는 모든 사람과 20 개 이상의 언어를 위해 일반화되도록 개발되었습니다. 일반적으로 다음과 같은 단점이 있습니다
.-구성 필요 (SWIG .i 템플릿), 때로는 까다 로움,
-일부 특수 사례 처리 부족 (Python 속성 추가 참조),
-일부 언어의 성능 부족.

파이썬 단점 :

1) 코드 스타일 불일치 . C ++와 python은 매우 다른 코드 스타일을 가지고 있습니다 (확실히 분명합니다). 타겟 코드를보다 Python으로 만들 수있는 가능성은 매우 제한적입니다. 예를 들어, getter 및 setter에서 속성을 만드는 것은 매우 중요합니다. 참조 이 Q & A를

2) 광범위한 커뮤니티 부족 . SWIG에는 좋은 문서가 있습니다. 그러나 문서에없는 것을 발견하면 정보가 전혀 없습니다. 블로그 나 인터넷 검색은 도움이되지 않습니다. 그래서 그런 경우에 SWIG에서 생성 된 코드를 엄청나게 파헤쳐 야합니다. 끔찍합니다.

장점 :

  • 간단한 경우에는 정말 빠르고 쉽고 간단합니다.

  • swig 인터페이스 파일을 한 번 생성 한 경우이 C ++ 코드를 다른 20 개 이상의 언어 (!!!)로 래핑 할 수 있습니다.

  • SWIG에 대한 한 가지 큰 관심사는 성능입니다. 2.04 버전부터 SWIG에는 '내장'플래그가 포함되어 SWIG를 다른 자동화 된 래핑 방법보다 훨씬 빠르게 만듭니다. 적어도 일부 벤치 마크 는 이것을 보여줍니다.


SWIG를 언제 사용합니까?

그래서 나는 swig가 사용하기에 좋은 두 가지 경우를 스스로 결론지었습니다.

2) 여러 언어에 대한 C ++ 코드를 래핑해야하는 경우 . 또는 잠재적으로 여러 언어로 코드를 배포해야 할 때가있을 수 있습니다. 이 경우 SWIG를 사용하면 신뢰할 수 있습니다.

1) 최종 사용을 위해 일부 C ++ 라이브러리의 여러 함수 빠르게 래핑 해야하는 경우 .


라이브 경험

업데이트 :
SWIG를 이용하여 우리 도서관을 전환 한 지 1 년 반이 지났습니다.

먼저 파이썬 버전을 만들었습니다. 우리가 SWIG에 문제를 겪었던 순간이있었습니다. 사실입니다. 하지만 지금은 라이브러리를 Java와 .NET으로 확장했습니다. 그래서 우리는 1 개의 SWIG로 3 개의 언어를 가지고 있습니다. 그리고 SWIG 는 많은 시간을 절약하는 측면에서 흔들린다 고 말할 수 있습니다.

업데이트 2 :
이 라이브러리에 SWIG를 사용하는 데 2 ​​년이 걸립니다. SWIG는 빌드 시스템에 통합됩니다. 최근에 우리는 C ++ 라이브러리의 주요 API 변경이있었습니다. SWIG는 완벽하게 작동했습니다. 우리가 할 필요가있는 유일한 방법은 우리의 있도록 .I 파일을 몇 % 이름 변경을 추가하는 것입니다 CppCamelStyleFunctions()이제 looks_more_pythonish파이썬한다. 처음에는 발생할 수있는 몇 가지 문제에 대해 걱정했지만 잘못된 것은 없습니다. 그것은 훌륭했다. 몇 가지 편집과 모든 것이 3 개 언어로 배포됩니다. 이제 우리의 경우 SWIG를 사용하는 것이 좋은 솔루션이라고 확신합니다.

업데이트 3 :
우리 도서관에 SWIG를 사용하는 것은 3 년 이상입니다. 주요 변경 사항 : 파이썬 부분이 순수 파이썬으로 완전히 재 작성되었습니다. 그 이유는 현재 라이브러리의 대부분의 애플리케이션에 Python이 사용되기 때문입니다. 순수 파이썬 버전이 C ++ 래핑보다 느리게 작동하더라도 사용자가 네이티브 라이브러리로 어려움을 겪지 않고 순수 파이썬으로 작업하는 것이 더 편리합니다.

SWIG는 여전히 .NET 및 Java 버전에 사용됩니다.

여기서 주요 질문은 "프로젝트를 처음부터 시작했다면 파이썬에 SWIG를 사용할까요?"입니다. 우리는 할거에요! SWIG를 통해 제품을 여러 언어로 신속하게 배포 할 수있었습니다. 일정 기간 동안 작동하여 사용자 요구 사항을 더 잘 이해할 수있는 기회를 제공했습니다.


CTypes는 SWIG보다 매우 멋지고 훨씬 쉽지만 잘못되거나 악의적으로 작성된 파이썬 코드가 실제로 파이썬 프로세스를 충돌시킬 수 있다는 단점이 있습니다. 부스트 파이썬 도 고려해야 합니다. IMHO 그것은 최종 파이썬 인터페이스에 대한 더 많은 제어를 제공하면서 실제로 swig보다 쉽습니다. 어쨌든 C ++를 사용하는 경우 믹스에 다른 언어를 추가하지 마십시오.


내 경험상 ctypes에는 큰 단점이 있습니다. 무언가 잘못되면 (복잡한 인터페이스에 대해 변함없이) 디버그하는 것은 지옥입니다.

문제는 스택의 큰 부분이 ctypes / ffi 마법에 의해 가려지고 특정 지점에 도달 한 방법과 매개 변수 값이 왜 그런지 결정하는 쉬운 방법이 없다는 것입니다.


고수준 Python 코드와 저수준 C 코드를 연결하는 역할을 할 수있는 Pyrex 를 사용할 수도 있습니다 . 예를 들어 lxml 은 Pyrex로 작성됩니다.


저는 반대되는 말을하려고합니다. 가능하다면 표준 Python API를 사용하여 확장 라이브러리를 작성해야 합니다 . C와 Python 관점 모두에서 정말 잘 통합되어 있습니다. Perl API에 대한 경험이 있다면 매우 즐거운 놀라움을 느끼실 것입니다.

Ctypes도 좋지만 다른 사람들이 말했듯이 C ++를 수행하지 않습니다.

포장하려는 도서관의 크기는 얼마입니까? 코드베이스는 얼마나 빨리 변경됩니까? 다른 유지 관리 문제가 있습니까? 이것들은 아마도 파이썬 바인딩을 작성하는 가장 좋은 방법의 선택에 영향을 미칠 것입니다.


ctypes is great, but does not handle C++ classes. I've also found ctypes is about 10% slower than a direct C binding, but that will highly depend on what you are calling.

If you are going to go with ctypes, definitely check out the Pyglet and Pyopengl projects, that have massive examples of ctype bindings.


Just wanted to add a few more considerations that I didn't see mentioned yet. [EDIT: Ooops, didn't see Mike Steder's answer]

If you want to try using a non Cpython implementation (like PyPy, IronPython or Jython), then ctypes is about the only way to go. PyPy doesn't allow writing C-extensions, so that rules out pyrex/cython and Boost.python. For the same reason, ctypes is the only mechanism that will work for IronPython and (eventually, once they get it all working) jython.

As someone else mentioned, no compilation is required. This means that if a new version of the .dll or .so comes out, you can just drop it in, and load that new version. As long as the none of the interfaces changed, it's a drop in replacement.


Something to keep in mind is that SWIG targets only the CPython implementation. Since ctypes is also supported by the PyPy and IronPython implementations it may be worth writing your modules with ctypes for compatibility with the wider Python ecosystem.


I have found SWIG to be be a little bloated in its approach (in general, not just Python) and difficult to implement without having to cross the sore point of writing Python code with an explicit mindset to be SWIG friendly, rather than writing clean well-written Python code. It is, IMHO, a much more straightforward process to write C bindings to C++ (if using C++) and then use ctypes to interface to any C layer.

If the library you are interfacing to has a C interface as part of the library, another advantage of ctypes is that you don't have to compile a separate python-binding library to access third-party libraries. This is particularly nice in formulating a pure-python solution that avoids cross-platform compilation issues (for those third-party libs offered on disparate platforms). Having to embed compiled code into a package you wish to deploy on something like PyPi in a cross-platform friendly way is a pain; one of my most irritating points about Python packages using SWIG or underlying explicit C code is their general inavailability cross-platform. So consider this if you are working with cross-platform available third party libraries and developing a python solution around them.

As a real-world example, consider PyGTK. This (I believe) uses SWIG to generate C code to interface to the GTK C calls. I used this for the briefest time only to find it a real pain to set up and use, with quirky odd errors if you didn't do things in the correct order on setup and just in general. It was such a frustrating experience, and when I looked at the interace definitions provided by GTK on the web I realized what a simple excercise it would be to write a translator of those interface to python ctypes interface. A project called PyGGI was born, and in ONE day I was able to rewrite PyGTK to be a much more functiona and useful product that matches cleanly to the GTK C-object-oriented interfaces. And it required no compilation of C-code making it cross-platform friendly. (I was actually after interfacing to webkitgtk, which isn't so cross-platform). I can also easily deploy PyGGI to any platform supporting GTK.

ReferenceURL : https://stackoverflow.com/questions/135834/python-swig-vs-ctypes

반응형