Python: SWIG vs ctypes

W Pythonie, w jakich okolicznościach SWIG jest lepszym Wyborem niż ctypes do wywoływania punktów wejścia w bibliotekach współdzielonych? Załóżmy, że nie masz jeszcze plików interfejsu SWIG.

Jakie są wskaźniki wydajności tych dwóch?

Author: David Nehme, 2008-09-26

10 answers

SWIG generuje (raczej brzydki) kod C lub c++. Jest prosty w użyciu dla prostych funkcji (rzeczy, które można przetłumaczyć bezpośrednio) i dość łatwy w użyciu dla bardziej złożonych funkcji (takich jak funkcje z parametrami wyjściowymi, które wymagają dodatkowego kroku tłumaczenia do reprezentowania w Pythonie.) Dla bardziej wydajnych interfejsów często trzeba zapisać bity C jako część pliku interfejsu. Do czegokolwiek poza prostym użytkowaniem będziesz musiał wiedzieć o Cpythonie i o tym, jak reprezentuje on obiekty-nie trudno, ale o czym trzeba pamiętać.

Ctypes umożliwia bezpośredni dostęp do funkcji C, struktur i innych danych oraz ŁADOWANIE DOWOLNYCH bibliotek współdzielonych. Nie musisz pisać żadnego C do tego, ale musisz zrozumieć, jak działa C. Jest to, można argumentować, druga strona SWIG: nie generuje kodu i nie wymaga kompilatora w czasie wykonywania, ale dla czegokolwiek, ale prostego użytkowania wymaga, aby zrozumieć, jak rzeczy takie jak typy danych C, odlewanie, zarządzanie pamięcią i / align = "left" / Należy również ręcznie lub automatycznie przetłumaczyć struktury C, związki i tablice na równoważną strukturę danych ctypes, w tym odpowiedni układ pamięci.

Jest prawdopodobne, że w czystym wykonaniu, SWIG jest szybszy niż ctypes -- ponieważ zarządzanie wokół rzeczywistej pracy odbywa się w C w compiletime, a nie w Pythonie w czasie wykonywania. Jednak, chyba że interfejs wiele różnych funkcji C, ale każda tylko kilka razy, jest mało prawdopodobne, że narzut będzie naprawdę zauważalne.

W czasie rozwoju ctypes ma znacznie niższy koszt uruchamiania: nie musisz uczyć się o plikach interfejsu, nie musisz generować .pliki c i skompilować je, nie trzeba sprawdzać i wyciszyć Ostrzeżenia. Możesz po prostu wskoczyć i zacząć używać jednej funkcji C przy minimalnym wysiłku, a następnie rozszerzyć ją na więcej. A Ty możesz testować i wypróbowywać rzeczy bezpośrednio w interpreterze Pythona. Owijanie dużej ilości kodu jest nieco żmudne, chociaż istnieją próby, aby prostsze (jak ctypes-configure.)

SWIG, z drugiej strony, może być używany do generowania wrapperów dla wielu języków (z wyjątkiem specyficznych dla języka szczegółów, które wymagają wypełnienia, jak niestandardowy kod C, O którym wspomniałem powyżej.) Podczas owijania dużo i dużo kodu, który SWIG może obsłużyć z niewielką pomocą, generowanie kodu może być również o wiele prostsze w konfiguracji niż odpowiedniki ctypes.

 60
Author: Thomas Wouters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 20:47:28

Mam bogate doświadczenie w używaniu swig. SWIG twierdzi, że jest to szybkie rozwiązanie do pakowania rzeczy. Ale w prawdziwym życiu...


Wady:

SWIG jest opracowany tak, aby był ogólny, dla wszystkich i dla ponad 20 języków. Generalnie prowadzi to do wad:
- wymaga konfiguracji (SWIG .i szablonów), czasami jest to trudne,
- brak leczenia niektórych szczególnych przypadków (patrz dalej właściwości Pythona),
- brak wydajności dla niektórych języków.

Python wady:

1) niespójność stylu kodu . C++ i python mają bardzo różne style kodu (to oczywiste, oczywiście), możliwości swig uczynienia kodu docelowego bardziej pythonish jest bardzo ograniczona. Jako przykład, jest to butt-heart do tworzenia właściwości z getterów i setterów. Zobacz to q&a

2) brak szerokiej społeczności . Swig ma dobrą dokumentację. Ale jeśli ktoś złapał coś, czego nie ma w dokumentacji, nie ma informacji w ogóle. Żadne blogi ani googling nie pomagają. Trzeba więc mocno kopać w takich przypadkach wygenerowany kod SWIG... To straszne, mogę powiedzieć...

Procs:

  • W prostych przypadkach jest to naprawdę szybkie, łatwe i proste

  • Jeśli raz stworzyłeś pliki interfejsu swig, możesz zawinąć ten kod C++ do dowolnego z ponad 20 języków (!!!).

  • Jednym z największych problemów SWIG jest występ. Od wersji 2.04 SWIG zawiera flagę '- built', która sprawia, że SWIG nawet szybciej niż inne zautomatyzowane sposoby owijania. Przynajmniej niektóre benchmarki pokazują to.


Kiedy stosować SWIG?

Więc doszedłem do wniosku, że dwa przypadki, kiedy swig jest dobry w użyciu:

2) jeśli trzeba zawinąć kod C++ dla kilku języków . Lub jeśli potencjalnie może być czas, kiedy trzeba rozpowszechnić kod dla kilku języków. Korzystanie z SWIG jest niezawodne w tym przypadku.

1) jeśli trzeba szybko zawiń tylko kilka funkcji z jakiejś biblioteki C++ do użytku końcowego.


Live experience

Update :
Minęło półtora roku, jak zrobiliśmy konwersję naszej biblioteki za pomocą SWIG.

Najpierw stworzyliśmy wersję Pythona.Było kilka chwil, kiedy doświadczyliśmy kłopotów z SWIG - to prawda. Ale teraz rozszerzyliśmy naszą bibliotekę do Java i. NET. więc mamy 3 języki z 1 SWIG. I mogę powiedzieć, że SWIG rocks w kategoriach oszczędność czasu.

Aktualizacja 2:
To dwa lata, jak używamy SWIG dla tej biblioteki. SWIG jest zintegrowany z naszym systemem budowania. Ostatnio mieliśmy poważną zmianę API biblioteki C++. SWIG zadziałał idealnie. Jedyne co musimy zrobić to dodać kilka % Zmień nazwę na .i files so our CppCamelStyleFunctions() now looks_more_pythonish in python. Najpierw martwiłem się o pewne problemy, które mogą się pojawić, ale nic nie poszło źle. To było niesamowite. Tylko kilka edycji i wszystko dystrybuowane w 3 językach. Teraz jestem przekonani, że dobrym rozwiązaniem było zastosowanie SWIG w naszym przypadku.

Aktualizacja 3:
To jest 3+ lat używamy SWIG dla naszej biblioteki. duża zmiana: część Pythona została całkowicie przepisana w czystym Pythonie. Powodem jest to, że python jest obecnie używany w większości aplikacji naszej biblioteki. Nawet jeśli czysta wersja Pythona działa wolniej niż owijanie C++, wygodniej jest użytkownikom pracować z czystym Pythonem, a nie borykać się z natywnymi bibliotekami.

SWIG jest nadal używany dla wersji. NET i Java.

Główne pytanie tutaj " Czy użylibyśmy SWIG dla Pythona, gdybyśmy zaczęli projekt od początku?". Tak! SWIG pozwolił nam na szybką dystrybucję naszego produktu na wiele języków. Działał przez pewien czas, który dał nam możliwość lepszego zrozumienia wymagań naszych użytkowników.

 83
Author: MajesticRa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 11:35:24

CTypes jest bardzo fajny i dużo łatwiejszy niż SWIG, ale ma tę wadę, że źle lub złośliwie napisany kod Pythona może faktycznie zawiesić proces Pythona. Należy również rozważyć boost python. IMHO jest to rzeczywiście łatwiejsze niż swig, zapewniając jednocześnie większą kontrolę nad ostatecznym interfejsem Pythona. Jeśli i tak używasz C++, nie dodajesz również innych języków do swojej mieszanki.

 13
Author: David Nehme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 20:35:17

Z mojego doświadczenia wynika, że ctypes ma dużą wadę: gdy coś pójdzie nie tak (i zawsze będzie to miało miejsce w przypadku wszystkich złożonych interfejsów), to jest piekło do debugowania.

Problem polega na tym, że duża część twojego stosu jest zasłonięta przez ctypes / FFI magic i nie ma łatwego sposobu na określenie, w jaki sposób dotarłeś do określonego punktu i dlaczego wartości parametrów są tym, czym są..

 10
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-21 01:36:28

Możesz również użyć Pyrex , który może działać jako klej pomiędzy wysokopoziomowym kodem Pythona a niskopoziomowym kodem C. lxml jest napisany na przykład w Pyrexie.

 8
Author: Torsten Marek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 20:54:22

Będę kontrarian i sugeruję, że jeśli możesz, powinieneś napisać swoją bibliotekę rozszerzeń przy użyciu standardowego API Pythona . Jest naprawdę dobrze zintegrowany z perspektywy C i Pythona... jeśli masz jakiekolwiek doświadczenie z API Perla, znajdziesz to Bardzo miłą niespodziankę.

Ctypes też jest ładny, ale jak inni mówili, nie robi C++.

Jak duża jest biblioteka, którą próbujesz zapakować? Jak szybko zmienia się kod? Inne problemy z konserwacją? Wszystko to prawdopodobnie wpłynie na wybór najlepszego sposobu zapisu wiązań Pythona.

 7
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-05 19:39:27

Ctypes jest świetny, ale nie obsługuje klas C++. Odkryłem również, że ctypes jest o 10% wolniejszy niż bezpośrednie wiązanie C, ale to zależy od tego, co nazywasz.

Jeśli zamierzasz używać ctype, koniecznie sprawdź projekty Pyglet i Pyopengl, które mają ogromne przykłady wiązań ctype.

 6
Author: Peter Shinners,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 21:22:15

Chciałem tylko dodać jeszcze kilka uwag, których jeszcze nie widziałem. [EDIT: Ooops, nie widziałem odpowiedzi Mike ' a Stedera]

Jeśli chcesz spróbować użyć implementacji innej niż Cpython (jak PyPy, IronPython lub Jython), to ctypes jest jedynym sposobem, aby przejść. PyPy nie pozwala na pisanie rozszerzeń C, więc wyklucza pyrex / cython i Boost.python. Z tego samego powodu ctypes jest jedynym mechanizmem, który będzie działał dla IronPython i (w końcu, gdy wszystko będzie działać) jython.

Jak ktoś inny wspomniał, kompilacja nie jest wymagana. Oznacza to, że jeśli nowa wersja .dll lub. więc wychodzi, możesz po prostu wrzucić go i załadować nową wersję. Tak długo, jak żaden z interfejsów się nie zmienił, jest to spadek wymiany.

 5
Author: Sean Toner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 06:13:02

Należy pamiętać, że SWIG celuje tylko w implementację CPython. Ponieważ ctypes jest również wspierany przez implementacje PyPy i IronPython, może warto napisać swoje moduły z ctypes dla kompatybilności z szerszym ekosystemem Pythona.

 3
Author: stderr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-25 05:35:20

Uważam, że SWIG jest trochę nadęty w swoim podejściu (ogólnie rzecz biorąc, nie tylko Python) i trudny do zaimplementowania bez konieczności przekraczania bolesnego punktu pisania kodu Pythona z wyraźnym nastawieniem, aby być przyjaznym SWIGOWI, zamiast pisać czysty dobrze napisany kod Pythona. Jest to, IMHO, o wiele prostszy proces, aby napisać wiązania C do C++ (jeśli używasz C++), a następnie użyć ctypes do interfejsu do dowolnej warstwy C.

Jeśli Biblioteka, z którą się łączysz, ma interfejs C jako kolejną zaletą ctypes jest to, że nie trzeba kompilować oddzielnej biblioteki wiążącej Pythona, aby uzyskać dostęp do bibliotek innych firm. Jest to szczególnie miłe w formułowaniu czystego rozwiązania Pythona, które pozwala uniknąć problemów z kompilacją między platformami (w przypadku bibliotek stron trzecich oferowanych na różnych platformach). Konieczność osadzania skompilowanego kodu w pakiecie, który chcesz wdrożyć na czymś takim jak PyPi w sposób przyjazny dla wielu platform, jest bólem; jednym z moich najbardziej irytujących punktów na temat Pakiety Pythona wykorzystujące SWIG lub bazujący na jawnym kodzie C to ich ogólna niedostępność między platformami. Rozważ to, jeśli pracujesz z wieloplatformowymi dostępnymi bibliotekami innych firm i rozwijasz rozwiązanie Pythona wokół nich.

Jako przykład w świecie rzeczywistym, rozważ PyGTK. To (jak sądzę) używa SWIG do generowania kodu C do interfejsu do wywołań GTK C. Użyłem tego przez najkrótszy czas, tylko po to, aby znaleźć prawdziwy ból w konfiguracji i użyciu, z dziwacznymi dziwnymi błędami, jeśli nie zrobiłeś rzeczy w odpowiedniej kolejności na konfiguracji i po prostu w ogóle. To było takie frustrujące doświadczenie, a kiedy spojrzałem na definicje interace dostarczone przez GTK w Internecie, zdałem sobie sprawę, jak prostym ćwiczeniem byłoby napisanie tłumacza tych interfejsów do interfejsu python ctypes. Powstał projekt o nazwie PyGGI i w ciągu jednego dnia udało mi się przepisać PyGTK na znacznie bardziej funkcjonalny i użyteczny produkt, który idealnie pasuje do interfejsów C-obiektowych GTK. I wymagało nie kompilacja C-kodu czyniąc go przyjaznym dla wielu platform. (Właściwie po nawiązaniu połączenia z webkitgtk, które nie jest tak wieloplatformowe). Mogę również łatwo wdrożyć PyGGI na dowolną platformę obsługującą GTK.

 -1
Author: nak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-28 15:17:46