C 라이브러리를 파이썬으로 감싸기 : C, Cython 또는 ctypes?


284

파이썬 응용 프로그램에서 C 라이브러리를 호출하고 싶습니다. 전체 API를 래핑하고 싶지 않으며 내 경우와 관련된 함수 및 데이터 유형 만 래핑하고 싶습니다. 내가 볼 때 세 가지 선택이 있습니다.

  1. C로 실제 확장 모듈을 만드십시오. 아마도 과잉 일 것입니다. 또한 확장 쓰기 학습의 오버 헤드를 피하고 싶습니다.
  2. Cython 을 사용 하여 C 라이브러리에서 Python으로 관련 파트를 노출하십시오.
  3. ctypes외부 라이브러리와 통신하는 데 사용하여 Python에서 모든 작업 을 수행하십시오.

2) 또는 3)이 더 나은 선택인지 확실하지 않습니다. 3)의 장점은 ctypes표준 라이브러리의 일부이며 결과 코드는 순수한 파이썬 일 것입니다.하지만 그 이점이 실제로 얼마나 큰지는 확실하지 않습니다.

어느 쪽을 선택해도 더 많은 장단점이 있습니까? 어떤 접근법을 권장합니까?


편집 : 모든 답변에 감사드립니다. 이는 비슷한 것을하려고하는 사람에게 훌륭한 자료를 제공합니다. 물론이 결정은 여전히 ​​단일 사례에 대해 내려져야합니다. "이것이 옳은 것"인 사람은 아무도 없습니다. 내 경우에는 아마도 ctypes를 사용하지만 다른 프로젝트에서 Cython을 시험해보기를 기대합니다.

하나의 진정한 대답이 없기 때문에 하나를 받아들이는 것은 다소 임의적입니다. 나는 ctypes에 대한 좋은 통찰력을 제공하고 현재 가장 인기있는 답변이므로 FogleBird의 답변을 선택했습니다. 그러나 좋은 답변을 얻으려면 모든 답변을 읽으십시오.

다시 감사합니다.


3
어느 정도까지 관련된 특정 응용 프로그램 (라이브러리의 기능)은 접근 방식의 선택에 영향을 줄 수 있습니다. 우리는 ctypes를 사용하여 다양한 hardare (예 : 오실로스코프)에 대해 공급 업체가 제공 한 DLL과 통신했지만, Cython 또는 SWIG에 비해 추가 오버 헤드로 인해 숫자 처리 라이브러리와 통신하기 위해 ctype을 먼저 선택하지는 않습니다.
Peter Hansen

1
지금 당신은 당신이 찾고 있던 것이 있습니다. 네 가지 답변. (누군가도 SWIG를 찾았습니다) 의미 지금은 4 개 선택 대신 3. 가지고
루카 Rahne을

@ralu 저도 그렇게합니다 :-) 그러나 진지하게, 나는 "여기에 당신이해야 할 일이 있습니다"라는 프로 / 콘 테이블이나 하나의 대답을 기대하지 않았습니다. 의사 결정에 관한 질문은 가능한 모든 선택의 "팬"이 그 이유를 제시하는 것이 가장 좋습니다. 그런 다음 커뮤니티 투표는 본인의 작업 (논쟁을보고 내 사건에 적용하고 제공된 출처를 읽는 등)과 마찬가지로 그 역할을 수행합니다. 짧은 이야기 : 여기에 좋은 대답이 있습니다.
balpha

어떤 접근법을 사용 하시겠습니까? :)
FogleBird 2009

1
내가 아는 한 (실패하면 수정하십시오) Cython은 Pyrex의 포크이며 더 많은 개발이 진행되어 Pyrex가 거의 쓸모가 없습니다.
balpha

답변:


115

ctypes 빨리 끝내기위한 최선의 방법이며, 파이썬을 작성하는 동안 함께 일하게되어 기쁩니다!

나는 최근 ctypes를 사용하여 USB 칩과 통신하기 위해 FTDI 드라이버를 감쌌다 . 나는 하루 종일 하루 안에 모든 일을하고 일했다. (필요한 기능, 약 15 가지 기능 만 구현했습니다).

이전 에는 동일한 목적 으로 타사 모듈 PyUSB를 사용하고있었습니다 . PyUSB는 실제 C / Python 확장 모듈입니다. 그러나 PyUSB는 읽기 / 쓰기 차단을 수행 할 때 GIL을 공개하지 않았기 때문에 문제가되었습니다. 그래서 나는 ctypes를 사용하여 우리 자신의 모듈을 작성했습니다.

주목해야 할 점은 ctypes는 #define사용중인 라이브러리의 상수와 내용에 대해 알지 못하고 함수 만 알고 있으므로 해당 상수를 자신의 코드로 재정의해야한다는 것입니다.

다음은 코드가 어떻게 보이는지에 대한 예입니다 (많은 점이 찍히고 요점을 보여 주려고 시도했습니다).

from ctypes import *

d2xx = WinDLL('ftd2xx')

OK = 0
INVALID_HANDLE = 1
DEVICE_NOT_FOUND = 2
DEVICE_NOT_OPENED = 3

...

def openEx(serial):
    serial = create_string_buffer(serial)
    handle = c_int()
    if d2xx.FT_OpenEx(serial, OPEN_BY_SERIAL_NUMBER, byref(handle)) == OK:
        return Handle(handle.value)
    raise D2XXException

class Handle(object):
    def __init__(self, handle):
        self.handle = handle
    ...
    def read(self, bytes):
        buffer = create_string_buffer(bytes)
        count = c_int()
        if d2xx.FT_Read(self.handle, buffer, bytes, byref(count)) == OK:
            return buffer.raw[:count.value]
        raise D2XXException
    def write(self, data):
        buffer = create_string_buffer(data)
        count = c_int()
        bytes = len(data)
        if d2xx.FT_Write(self.handle, buffer, bytes, byref(count)) == OK:
            return count.value
        raise D2XXException

다양한 옵션에 대한 벤치마킹 을 한 사람이 있습니다.

많은 클래스 / 템플릿 / 등으로 C ++ 라이브러리를 래핑해야한다면 주저 할 수 있습니다. 그러나 ctypes는 구조체와 잘 작동 하며 Python으로 콜백 할 수도 있습니다 .


5
ctypes에 대한 칭찬에 참여하지만 하나의 (언급되지 않은) 문제를 주목하십시오. ctypes는 분기를 지원하지 않습니다. ctypes를 사용하는 프로세스에서 분기하고 부모 및 자식 프로세스가 ctypes를 계속 사용하는 경우 공유 메모리를 사용하는 ctypes와 관련된 불쾌한 버그가 발생합니다.
Oren Shemesh

1
@OrenShemesh이 문제에 관해 더 읽어야 할 점이 있습니까? 부모 프로세스 만 ctypes()을 사용한다고 생각하기 때문에 현재 작업중 인 프로젝트로 안전하다고 생각 pyinotify하지만 문제를보다 철저히 이해하고 싶습니다.
zigg

이 구절은 나에게 많은 도움이 One thing to note is that ctypes won't know about #define constants and stuff in the library you're using, only the functions, so you'll have to redefine those constants in your own code.내가 거기에있는 상수를 정의해야합니다, 그래서 winioctl.h...
swdev

성능은 어떻습니까? ctypes병목 현상이 파이썬에서 C
로의

154

경고 : Cython 핵심 개발자의 의견.

나는 거의 항상 ctypes보다 Cython을 권장합니다. 그 이유는 업그레이드 경로가 훨씬 매끄 럽기 때문입니다. ctypes를 사용한다면, 처음에는 많은 것들이 간단 할 것입니다. 그리고 컴파일, 의존성 등을 작성하지 않고 일반 파이썬으로 FFI 코드를 작성하는 것이 좋습니다. 그러나 어느 시점에서 루프 또는 더 긴 일련의 상호 의존적 호출에서 C 라이브러리를 많이 호출해야한다는 것을 거의 확실하게 알 수 있으며 그 속도를 높이고 싶습니다. 그것이 ctypes로는 그렇게 할 수 없다는 것을 알게 될 것입니다. 또는 콜백 함수가 필요하고 Python 콜백 코드가 병목 현상이 발생하면 속도를 높이거나 C로 낮추십시오. 다시 ctypes로는 그렇게 할 수 없습니다.

Cython, OTOH를 사용하면 랩핑 및 호출 코드를 원하는만큼 얇거나 두껍게 만들 수 있습니다. 일반 Python 코드에서 C 코드를 간단하게 호출하여 시작할 수 있으며 Cython은 추가 호출 오버 헤드없이 Python 매개 변수에 대한 변환 오버 헤드가 매우 낮은 네이티브 C 호출로 변환합니다. C 라이브러리를 너무 많이 호출하는 시점에서 더 많은 성능이 필요하다는 것을 알게되면 정적 유형으로 주변 Python 코드에 주석을 달고 Cython이 C로 직접 최적화하도록 할 수 있습니다. 또는 호출을 피하고 루프를 알고리즘 적으로 특수화하고 강화하기 위해 Cython에서 C 코드의 일부를 다시 쓰기 시작할 수 있습니다. 빠른 콜백이 필요한 경우 적절한 서명을 가진 함수를 작성하고 C 콜백 레지스트리에 직접 전달하십시오. 다시 말하지만 오버 헤드가 없으며 일반 C 호출 성능을 제공합니다. 그리고 Cython에서 코드를 충분히 빨리 얻을 수없는 경우에도 C (또는 C ++ 또는 Fortran)로 코드의 중요한 부분을 다시 작성하여 Cython 코드에서 자연스럽고 기본적으로 호출 할 수 있습니다. 그러나 이것이 실제로 유일한 옵션 대신 최후의 수단이됩니다.

따라서 ctypes는 간단한 작업을 수행하고 빠르게 무언가를 실행하는 것이 좋습니다. 그러나 상황이 커지기 시작하면 Cython을 처음부터 더 잘 사용한다는 것을 알게 될 것입니다.


4
좋은 점은 +1입니다. 감사합니다! 병목 부분 만 Cython으로 옮기는 것이 실제로 오버 헤드의 많은 것인지 궁금합니다. 그러나 어떤 종류의 성능 문제가 예상되면 처음부터 Cython을 활용할 수도 있습니다.
balpha

이것은 여전히 ​​C와 Python을 모두 경험 한 프로그래머에게 적용됩니까? 이 경우 CMD (SIMD)의 벡터화가 때로는 더 간단하기 때문에 Python / ctypes가 더 나은 선택이라고 주장 할 수 있습니다. 그러나 그 외에는 Cython의 단점을 생각할 수 없습니다.
Alex van Houten

답변 해주셔서 감사합니다! Cython과 관련하여 문제가 된 한 가지 사항은 빌드 프로세스를 올바르게 수행하는 것입니다 (그러나 이전에는 Python 모듈을 작성하지 않아도됩니다). 전에 컴파일하거나 sdist 및 유사한 질문에 Cython 소스 파일을 포함시켜야합니다. 누군가 비슷한 문제 / 의심이있는 경우에 대비하여 블로그 게시물을 썼습니다 : martinsosic.com/development/2016/02/08/…
Martinsos

답변 해주셔서 감사합니다! Cython을 사용할 때의 한 가지 단점은 연산자 오버로드가 완전히 구현되지 않았다는 것입니다 (예 :) __radd__. 클래스가 내장 유형 (예 : intfloat) 과 상호 작용하도록 계획 할 때 이것은 특히 성가신 일 입니다. 또한 cython의 마술 메서드는 일반적으로 약간 버그가 있습니다.
Monolith

100

Cython은 그 자체로 매우 유용한 도구이며 학습 가치가 있으며 놀랍게도 Python 구문과 비슷합니다. Numpy를 사용하여 과학 컴퓨팅을 수행하는 경우 Cython은 빠른 매트릭스 작업을 위해 Numpy와 통합되기 때문에 갈 수 있습니다.

Cython은 Python 언어의 상위 집합입니다. 유효한 파이썬 파일을 던질 수 있으며 유효한 C 프로그램을 뱉어냅니다. 이 경우 Cython은 Python 호출을 기본 CPython API에 매핑합니다. 코드가 더 이상 해석되지 않기 때문에 속도가 50 % 향상 될 수 있습니다.

최적화를 얻으려면 타입 선언과 같은 코드에 대한 추가 사실을 Cython에 알려 주어야합니다. 충분히 말하면 코드를 순수 C로 끓일 수 있습니다. 즉, 파이썬의 for 루프는 C의 for 루프가됩니다. 여기에서 엄청난 속도 향상을 볼 수 있습니다. 여기에서 외부 C 프로그램에 연결할 수도 있습니다.

Cython 코드를 사용하는 것도 매우 쉽습니다. 나는 매뉴얼이 소리를 어렵게 만든다고 생각했다. 당신은 말 그대로 그냥 :

$ cython mymodule.pyx
$ gcc [some arguments here] mymodule.c -o mymodule.so

그런 다음 import mymodule파이썬 코드에서 C로 컴파일하는 것을 잊어 버릴 수 있습니다.

어쨌든 Cython은 설치 및 사용이 매우 쉽기 때문에 필요에 맞는지 확인하는 것이 좋습니다. 당신이 찾고있는 도구가 아닌 것으로 판명되면 낭비되지 않습니다.


1
문제 없어요. Cython의 좋은 점은 필요한 것만 배울 수 있다는 것입니다. 약간의 개선 만 원한다면 파이썬 파일을 컴파일하기 만하면됩니다.
carl December

18
"당신은 유효한 파이썬 파일을 던질 수 있고, 유효한 C 프로그램을 뱉어 낼 것입니다." <- 확실 하지는 않지만 다음과 같은 몇 가지 제한이 있습니다. docs.cython.org/src/userguide/limitations.html 대부분의 유스 케이스에는 문제가되지 않지만 완전하고 싶었습니다.
랜디 주사기

7
각 페이지에서 "대부분의 문제가 0.15에서 해결되었습니다"라고 표시 될 때까지 문제가 줄어 듭니다.
Henry Gomersall

3
또한 Cython 코드를 가져 오는 쉬운 방법이 있습니다. Cython 코드를 mymod.pyx모듈 로 작성한 다음 import pyximport; pyximport.install(); import mymod컴파일하면 장면 뒤에서 발생합니다.
Kaushik Ghose

3
@kaushik도 간단 pypi.python.org/pypi/runcython . 그냥 사용하십시오 runcython mymodule.pyx. pyximport와는 달리 더 까다로운 연결 작업에 사용할 수 있습니다. 단 한가지주의 할 점은 내가 20 줄의 bash를 작성했으며 편향 될 수 있다는 것입니다.
RussellStewart

42

파이썬 응용 프로그램에서 C 라이브러리를 호출하기 위해 ctypes에 대한 새로운 대안 인 cffi 도 있습니다 . FFI에 대한 새로운 모습을 제공합니다.

  • 그것은 매혹적인 깨끗한 방법으로 문제를 처리 (반대 하는 ctypes )
  • SWIG, Cython 등에서 비 Python 코드를 작성할 필요가 없습니다.

OP가 원했던 것처럼 확실히 포장 을 갈 수있는 길 입니다. cython은 핫 루프를 직접 작성하는 데 훌륭하게 들리지만 인터페이스의 경우 cffi는 단순히 ctype에서 직접 업그레이드합니다.
비행 양

21

나는 또 다른 하나를 던져 : SWIG

배우기 쉽고 많은 일을 잘하며 더 많은 언어를 지원하므로 배우는 데 많은 시간을 할애 할 수 있습니다.

SWIG를 사용하면 새로운 파이썬 확장 모듈을 만들지 만 SWIG를 사용하면 대부분의 작업을 수행 할 수 있습니다.


18

개인적으로 저는 C로 확장 모듈을 작성했습니다. 파이썬 C 확장에 겁 먹지 마십시오. 전혀 작성하기 어렵지 않습니다. 설명서는 매우 명확하고 도움이됩니다. 파이썬으로 C 확장을 처음 썼을 때, 한 번 작성하는 방법을 알아내는 데 약 한 시간이 걸렸다 고 생각합니다.


C 라이브러리 랩핑 당신은 실제로 여기에 코드를 찾을 수 있습니다 github.com/mdippery/lehmer
mipadi

1
@ forivall : 코드가 실제로 그렇게 유용한 것은 아니며 더 나은 난수 생성기가 있습니다. 컴퓨터에 백업 만 있습니다.
mipadi

2
동의했다. 파이썬의 C-API는 보이는 것처럼 거의 무섭지 않습니다 (C를 알고 있다고 가정). 그러나 파이썬 및 라이브러리, 리소스 및 개발자 저장소와는 달리 C로 확장을 작성할 때 기본적으로 사용자입니다. 아마도 유일한 단점 (일반적으로 C로 작성된 것과 다름).
멍청한 놈 사이 보트

1
@mipadi : 글쎄요.하지만 파이썬 2.x와 3.x는 다릅니다. Cython을 사용하여 확장을 작성하는 것이 더 편리합니다. Cython이 모든 세부 사항을 파악한 다음 생성 된 C 코드를 Python 2.x 또는 필요에 따라 3.x.
0xC0000022L

2
@ mipadi 그것은 github 링크가 죽은 것처럼 보이고 archive.org에서 사용할 수없는 것처럼 보입니다. 백업이 있습니까?
jrh

11

ctypes 는 이미 처리 할 컴파일 된 라이브러리 Blob (예 : OS 라이브러리)을 가지고있을 때 좋습니다. 그러나 호출 오버 헤드가 심각하므로 라이브러리에 많은 호출을하고 어쨌든 C 코드를 작성하거나 적어도 컴파일하는 경우 사이 톤 . 그것은 더 많은 작업이 아니며 결과 pyd 파일을 사용하는 것이 훨씬 빠르고 더 pythonic 일 것입니다.

나는 개인적으로 파이썬 코드의 빠른 속도 향상을 위해 cython을 사용하는 경향이 있습니다 (루프와 정수 비교는 cython이 특히 빛나는 두 영역입니다). 다른 라이브러리와 관련된 코드 / 줄 바꿈이 더 관련되어 있으면 Boost.Python으로 돌아갑니다 . Boost.Python은 설정하기가 까다로울 수 있지만 일단 작동하면 C / C ++ 코드를 간단하게 배치 할 수 있습니다.

cython은 또한 numpy 를 감싸는 데 훌륭 하지만 ( SciPy 2009 절차 에서 배운 ) numpy를 사용하지 않았으므로 이에 대해 언급 할 수 없습니다.


11

API가 정의 된 라이브러리가 이미 있다면 ctypes 약간의 초기화 만하면되고 익숙한 방식으로 라이브러리를 호출 할 수 있으므로 최선의 방법이라고 생각합니다.

Cython이나 C에서 확장 모듈 (매우 어렵지는 않음)을 만드는 것이 라이브러리를 호출하고 복잡한 시간이 많이 걸리는 작업을 수행 한 다음 결과를 Python에 전달하는 등 새로운 코드가 필요할 때 더 유용하다고 생각합니다.

간단한 프로그램에 대한 또 다른 접근법은 직접 외부 프로세스로 다른 프로세스를 수행하여 결과를 표준 출력으로 출력하고 하위 프로세스 모듈로 호출하는 것입니다. 때로는 가장 쉬운 방법입니다.

예를 들어, 콘솔 C 프로그램을 그렇게 만들거나 덜 작동시키는 경우

$miCcode 10
Result: 12345678

파이썬에서 호출 할 수 있습니다

>>> import subprocess
>>> p = subprocess.Popen(['miCcode', '10'], shell=True, stdout=subprocess.PIPE)
>>> std_out, std_err = p.communicate()
>>> print std_out
Result: 12345678

작은 문자열 형식을 사용하면 원하는 방식으로 결과를 얻을 수 있습니다. 표준 오류 출력을 캡처 할 수도 있으므로 매우 유연합니다.


이 답변에는 잘못된 것이 없지만 shell=True사용자가 실제로 쉘을 얻을 때 하위 프로세스를 호출 하면 쉽게 악용 될 수 있으므로 다른 사람들이 액세스 할 수 있도록 코드를 열면 사람들은 조심해야합니다 . 개발자가 단독 사용자 인 경우에는 문제가 없지만, 전 세계에는 이와 같은 것을 기다리는 성가신 사기꾼이 많이 있습니다.
Ben

7

Cython이 아닌 ctypes를 사용하게하고 다른 답변에 언급되지 않은 한 가지 문제가 있습니다.

ctypes를 사용하면 결과는 사용중인 컴파일러에 전혀 의존하지 않습니다. 기본 공유 라이브러리로 컴파일 될 수있는 언어를 사용하여 라이브러리를 작성할 수 있습니다. 어떤 시스템, 어떤 언어 및 어떤 컴파일러인지는 중요하지 않습니다. 그러나 Cython은 인프라에 의해 제한됩니다. 예를 들어, Windows에서 인텔 컴파일러를 사용하려면 cython을 작동시키는 것이 훨씬 까다 롭습니다. 컴파일러를 cython으로 "설명"하고이 정확한 컴파일러로 무언가를 다시 컴파일해야합니다. 이식성이 크게 제한됩니다.


4

Windows를 대상으로하고 일부 독점적 인 C ++ 라이브러리를 래핑하기로 선택한 경우 곧 다른 버전의 msvcrt***.dll(Visual C ++ Runtime)이 약간 호환되지 않을 수 있습니다 .

이는 Cython결과 wrapper.pydmsvcr90.dll (Python 2.7) 또는 msvcr100.dll (Python 3.x)에 연결되어 있으므로 사용하지 못할 수 있음을 의미합니다 . 줄 바꿈하는 라이브러리가 다른 버전의 런타임과 연결되어 있으면 운이 좋지 않습니다.

그런 다음 작업을 수행하려면 C ++ 라이브러리 용 C 랩퍼를 작성하고 해당 랩퍼 dll을 C ++ 라이브러리와 동일한 버전에 링크해야 msvcrt***.dll합니다. 그런 다음 ctypes런타임에 수동 롤 래퍼 dll을 동적으로로드 하는 데 사용하십시오.

따라서 다음 기사에서 자세히 설명하는 작은 세부 정보가 많이 있습니다.

"Beautiful Native Libraries (Python) ": http://lucumr.pocoo.org/2013/8/18/beautiful-native-libraries/


이 기사는 Microsoft 컴파일러의 호환성으로 인해 발생하는 문제와 관련이 없습니다. Windows에서 Cython 확장을 작동시키는 것은 그리 어렵지 않습니다. 나는 거의 모든 것에 MinGW를 사용할 수있었습니다. 좋은 파이썬 배포판이 도움이됩니다.
IanH

2
Windows에서 가능한 문제를 언급하여 +1합니다 (현재 가지고있는 ...). @IanH 그것은 일반적으로 창에 관한 것이 아니지만 파이썬 배포와 일치하지 않는 지정된 타사 라이브러리에 붙어 있으면 엉망입니다.
sebastian


2

나는 이것이 오래된 질문이라는 것을 알고 있지만 ctypes vs cython, 당신이 같은 것을 검색 할 때이 문제는 Google에 올라오고 , 여기에있는 대부분의 답변은 이미 능숙 cython하거나 c그 사람들을 배우기 위해 투자하는 데 필요한 실제 시간을 반영하지 않을 수 있는 사람들에 의해 작성되었습니다 솔루션을 구현합니다. 나는 둘 다 완전한 초보자입니다. 나는 cython전에 만지지 않았으며 에 대한 경험이 거의 없습니다 c/c++.

지난 이틀 동안 코드의 성능이 많은 부분을 파이썬보다 낮은 수준으로 위임하는 방법을 찾고있었습니다. 기본적으로 두 가지 간단한 함수로 구성된 in ctypes및 에서 코드를 구현했습니다 Cython.

처리해야 할 거대한 문자열 목록 이 있었습니다 . 공지 사항 liststring. c파이썬 문자열은 기본적으로 유니 코드이고 c문자열은 아니기 때문에 두 유형 모두의 유형과 완벽하게 일치 하지 않습니다. 파이썬의 목록은 단순히 c의 배열이 아닙니다.

여기 내 평결이 있습니다. 사용하십시오 cython. 파이썬에 더 유창하게 통합되며 일반적으로 작업하기가 더 쉽습니다. 무언가 잘못되면 ctypessegfault가 발생합니다. 적어도 cython가능한 한 스택 추적으로 컴파일 경고를 표시하고 유효한 python 객체를 쉽게 반환 할 수 있습니다 cython.

다음은 동일한 기능을 구현하기 위해 두 가지에 투자하는 데 필요한 시간에 대한 자세한 설명입니다. 나는 C / C ++ 프로그래밍을 거의하지 않았다.

  • 유형 :

    • 내 유니 코드 문자열 목록을 ac 호환 유형으로 변환하는 방법을 연구하는 데 약 2 시간이 걸렸습니다.
    • ac 함수에서 문자열을 올바르게 반환하는 방법에 대한 약 1 시간 여기 사실은 내 자신의 솔루션을 제공하는 SO 내가 기능을 작성한 후.
    • c로 코드를 작성하는 데 약 30 분이 걸리면 코드를 동적 라이브러리로 컴파일하십시오.
    • c코드가 작동하는지 확인하기 위해 파이썬으로 테스트 코드를 작성하는 데 10 분 .
    • 몇 시간 동안 테스트를 수행하고 c코드를 재정렬합니다 .
    • 그런 다음 c코드를 실제 코드베이스에 꽂고 기본적으로 처리기를 선택할 수 없으므로 모듈과 ctypes잘 작동하지 않는 것을 보았습니다 multiprocessing.
    • 약 20 분 동안 multiprocessing모듈을 사용하지 않도록 코드를 재정렬 하고 다시 시도했습니다.
    • 그런 다음 내 c코드의 두 번째 함수는 테스트 코드를 통과했지만 코드베이스에서 segfault를 생성했습니다. 글쎄, 이것은 아마도 엣지 케이스를 잘 점검하지 못하는 내 잘못 일 것입니다. 나는 빠른 해결책을 찾고있었습니다.
    • 약 40 분 동안 이러한 segfault의 가능한 원인을 확인하려고했습니다.
    • 함수를 두 개의 라이브러리로 나누고 다시 시도했습니다. 여전히 내 두 번째 기능에 대한 segfaults가있었습니다.
    • I 번째 함수의 이동의 첫 기능 사용할 수 있도록 결정 c코드 및 용도가 그것이 I가 가졌던 파이썬 루프의 두 번째 또는 세 번째 반복에서 UnicodeErrorI는 부호화 모든게 디코딩 비록 몇몇 위치에서 바이트들을 디코딩 약하지 명시 적으로.

이 시점에서 나는 대안을 찾기로 결정하고 다음을 조사하기로 결정했습니다 cython.

  • 사이 톤
    • cython hello world 를 읽는 10 분 .
    • 대신 cython을 사용하는 방법에 대해 SO 를 확인하는 15 분 .setuptoolsdistutils
    • Cython 유형 및 Python 유형 에 대한 10 분의 읽기 정적 타이핑을 위해 대부분의 내장 파이썬 유형을 사용할 수 있다는 것을 배웠습니다.
    • Cython 유형으로 파이썬 코드를 다시 주석 처리하는 15 분.
    • setup.py내 코드베이스에서 컴파일 된 모듈을 사용하도록 수정 10 분 .
    • multiprocessing코드베이스 버전에 모듈을 직접 연결했습니다 . 효과가있다.

물론, 나는 투자의 정확한시기를 측정하지 않았다. 내가 ctypes를 다룰 때 요구되는 정신적 노력으로 인해 시간에 대한 나의 인식이 약간주의를 기울인 경우가 매우 그렇다. 하지만 처리의 느낌을 전달해야 cython하고ctypes

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.