Frage

In Python, unter welchen Umständen ist eine bessere Wahl als ctypes SWIG für den Aufruf von Einspeisepunkten in gemeinsam genutzten Bibliotheken? Nehmen wir an, Sie nicht bereits über die SWIG Interface-Datei (en).
Was die Performance-Kennzahlen der beiden sind?

War es hilfreich?

Lösung

SWIG erzeugt (ziemlich hässlich) C oder C ++ Code. Es ist einfach für einfache Funktionen (Dinge, die direkt übersetzt werden können) zu verwenden und relativ einfach für komplexere Funktionen (wie zB Funktionen mit Ausgabeparametern, die einen zusätzlichen Übersetzungsschritt darzustellen in Python müssen.) Für leistungsstärkere Sie oft eine Schnittstelle müssen Bits von C als Teil der Schnittstellendatei schreiben. Für alles andere als einfach Gebrauch müssen Sie über CPython wissen und wie sie repräsentiert Objekte - nicht schwer, aber etwas im Auge behalten

.

ctypes können Sie direkt an C-Funktionen, Strukturen und andere Daten zugreifen und beliebige gemeinsam genutzte Bibliotheken laden. Sie brauchen kein C zu schreiben, aber Sie müssen verstehen, wie C arbeitet. Es ist, könnte man argumentieren, die Kehrseite der SWIG: es erzeugt keinen Code und es nicht einen Compiler zur Laufzeit benötigen, aber für alles anderes als einfache Anwendung macht es erforderlich, dass Sie Dinge wie die C-Datentypen zu verstehen, Gießen, Speicherverwaltung und die Ausrichtung der Arbeit. Sie müssen auch manuell oder automatisch C structs, Gewerkschaften und Arrays in die äquivalente ctypes Datenstruktur, einschließlich des Rechts Speicherlayout übersetzen.

Es ist wahrscheinlich, dass in reiner Ausführung, SWIG ist schneller als ctypes - weil das Management rund um die eigentliche Arbeit in C bei compiletime getan wird, statt in Python zur Laufzeit. Allerdings, wenn Sie eine Menge verschiedener C-Funktionen Schnittstelle aber jeweils nur ein paar Mal, es ist unwahrscheinlich, dass der Aufwand wirklich spürbar sein wird.

In Entwicklungszeit hat ctypes eine viel geringere Startkosten: Sie müssen nicht über Schnittstellen-Dateien zu erfahren, müssen Sie keine Dateien erzeugen .c und kompilieren sie, Sie müssen nicht auschecken und Schweigen Warnungen. Sie können nur in springen und starten Sie eine einzelne C-Funktion mit minimalem Aufwand verwenden, erweitern Sie es dann mehr. Und Sie erhalten zu testen und ausprobieren direkt in dem Python-Interpreter. eine Menge Code Wrapping ist etwas langweilig, obwohl es Versuche gibt, dass einfacher zu machen (wie ctypes konfigurieren.)

SWIG, auf der anderen Seite, kann verwendet werden, Wrapper für mehrere Sprachen (abgesehen von sprachspezifischen Details, die in Not füllen, wie der benutzerdefinierten C-Code ich oben erwähnt.) Zu erzeugen, wenn jede Menge Code Einwickeln, dass SWIG kann mit wenig Hilfe handhabt, kann die Code-Generierung auch viel einfacher sein, die ctypes Äquivalente einzurichten als.

Andere Tipps

Ich habe eine reiche Erfahrung Schluck verwenden. SWIG behauptet, dass es eine schnelle Lösung für die Verpackung Dinge ist. Aber im wirklichen Leben ...


Nachteile:

SWIG entwickeln allgemein zu sein, für jeden Geschmack und für mehr als 20 Sprachen. Im Allgemeinen ist es führt zu Nachteilen:
- Konfiguration (SWIG .i Vorlagen) benötigt, manchmal ist es schwierig,
- fehlende Behandlung von einigen Sonderfällen (siehe Python Eigenschaften weiter), Frankreich - Mangel an Performance für einige Sprachen.

Python Nachteile:

1) Code-Stil Inkonsistenz . C ++ und Python haben sehr unterschiedliche Codearten (das ist offensichtlich, natürlich), die Möglichkeiten eines swig machen Zielcode mehr Pythonish ist sehr begrenzt. Als Beispiel ist es stumpf Herz Eigenschaft von Getter und Setter zu erstellen. Siehe dieses q & a

2) Der Mangel an breiter Gemeinschaft . SWIG hat einige gute Dokumentation. Aber wenn man etwas gefangen, die nicht in der Dokumentation ist, gibt es überhaupt keine Informationen. Keine Blogs noch googeln hilft. So hat man zu stark graben SWIG Code erzeugt in solchen Fällen ... Das ist schrecklich, ich könnte sagen ...

Vorteile:

  • In einfachen Fällen ist es wirklich schnell, einfach und geradlinig

  • Wenn Sie einmal swig Interface-Dateien erzeugt, können Sie wickeln diese C ++ Code zu ANY anderen 20 Sprachen (!!!).

  • Eine große Sorge über SWIG ist eine Leistung. Seit der Version 2.04 SWIG enthält ‚-builtin‘ Flag, das als andere automatisierte Möglichkeiten der Verpackung SWIG noch schneller macht. Mindestens einige Benchmarks dies zeigt.


Wenn SWIG benutzen?

So schloss ich mich zwei Fälle, in denen die swig gut zu bedienen ist:

2) Wenn ein C ++ Code wickeln muss für mehrere Sprachen . Oder wenn möglicherweise könnte es eine Zeit sein, wenn man den Code für mehrere Sprachen verteilen muss. SWIG zu verwenden ist in diesem Fall zuverlässig.

1) Wenn man muss schnell wickeln nur einige Funktionen von einigen C ++ Bibliothek für den Endverbrauch.


Live-Erfahrung

Aktualisieren :
Es ist ein Jahr und eine Hälfte vergangen, als wir durch die Verwendung SWIG eine Umstellung unserer Bibliothek haben.

Zuerst machten wir eine Python-Version. Es gab mehrere Momente, in denen wir Probleme mit SWIG erlebt - es ist wahr. Aber jetzt haben wir unsere Bibliothek zu Java und .NET. So haben wir drei Sprachen mit 1 SWIG. Und ich könnte sagen, dass SWIG Felsen in Bezug auf eine Menge Zeit sparen.

Update 2 :
Es ist zwei Jahre als wir SWIG für diese Bibliothek verwenden. SWIG ist integriert in unserem Build-System. Vor kurzem hatten wir große API Änderung von C ++ Bibliothek. SWIG funktionierte perfekt. Das einzige, was wir tun mussten, ist mehrere% Umbenennungs Dateien hinzufügen .i so unser CppCamelStyleFunctions() jetzt in Python looks_more_pythonish. Zuerst war ich über einige Probleme besorgt, die entstehen könnten, aber nichts schief gelaufen ist. Es war wundervoll. Nur einige Änderungen und alles in 3 Sprachen verteilt. Jetzt bin ich zuversichtlich, dass es eine gute Lösung zu verwenden SWIG in unserem Fall war.

Update 3 :
Es ist 3 + Jahre wir SWIG für unsere Bibliothek nutzen. Wichtige Änderung : python Teil völlig wurde in reinem Python geschrieben. Der Grund dafür ist, dass Python für die Mehrzahl der Anwendungen unserer Bibliothek jetzt verwendet wird. Auch wenn die reine Python-Version arbeitet langsamer als C ++ Verpackung, ist es bequemer für Anwender mit reinem Python zu arbeiten, nicht mit nativen Bibliotheken zu kämpfen.

SWIG wird noch verwendet für .NET und Java-Versionen.

Die Hauptfrage hier „Würden wir SWIG für Python verwenden, wenn wir das Projekt von Anfang an? Started“. Wir würden! SWIG uns erlaubt, schnell auf unser Produkt zu vielen Sprachen zu verteilen. Er arbeitete für einen bestimmten Zeitraum which gab uns die Möglichkeit für eine bessere unsere Nutzer Anforderungen zu verstehen.

ctypes ist sehr cool und viel einfacher als SWIG, aber es hat den Nachteil, die schlecht oder bösartig geschriebenen Python-Code tatsächlich den Python-Prozess zum Absturz bringen können. Sie sollten auch steigern Python betrachten. IMHO ist es tatsächlich einfacher als swig, während Sie mehr Kontrolle über die endgültige Python-Schnittstelle zu geben. Wenn Sie C ++ verwenden sowieso, Sie auch hinzufügen, keine andere Sprachen zu Ihrem Mix.

Nach meiner Erfahrung ctypes hat einen großen Nachteil:., Wenn etwas schief geht (und es wird immer für alle komplexen Schnittstellen), ist es eine Hölle zu debug

Das Problem ist, dass ein großer Teil des Stapels von ctypes / ffi Magie verdeckt ist, und es gibt keinen einfachen Weg, um zu bestimmen, wie haben Sie zu einem bestimmten Punkt und warum Parameterwerte sind, was sie sind ..

Sie können auch verwenden Pyrex , der wirkt als Kleber zwischen High-Level-Python-Code und Low-Level-C-Code. lxml wird zum Beispiel in Pyrex, geschrieben.

Ich werde Contrarian sein und lassen vermuten, dass, wenn Sie können, Sie Ihre Erweiterungsbibliothek schreiben sollte die Standard-Python-API . Es ist wirklich gut integriert sowohl in C und Python Perspektive ... wenn Sie keine Erfahrung mit dem Perl-API haben, werden Sie es eine sehr angenehme Überraschung finden.

Ctypes schön ist auch, aber wie andere schon gesagt haben, es nicht tun C ++.

Wie groß ist die Bibliothek, die Sie zu wickeln sind versuchen? Wie schnell ändert sich die Code-Basis? Alle anderen Wartungsprobleme? Diese werden alle wahrscheinlich Einfluss auf die Wahl des besten Weg, um die Python-Bindings zu schreiben.

ctypes ist groß, aber C ++ Klassen nicht verarbeitet. Ich habe auch festgestellt ctypes etwa 10% langsamer als direktes C-Bindung, aber das wird sehr davon abhängen, was Sie anrufen.

Wenn Sie vorhaben, mit ctypes zu gehen, auf jeden Fall die Pyglet und PyOpenGL Projekte überprüfen, dass massive Beispiele für ctype Bindungen haben.

Ich wollte nur noch ein paar Überlegungen hinzufügen, die ich noch nicht erwähnt gesehen habe. [EDIT: Ooops, nicht Mike Steder Antwort sehen]

Wenn Sie eine nicht CPython Implementierung mit (wie PyPy, Ironpython oder Jython) versuchen wollen, ctypes dann geht es um den einzigen Weg zu gehen. PyPy erlaubt keine C-Erweiterungen zu schreiben, so dass Pyrex / cython und Boost.Python ausgeschlossen ist. Aus dem gleichen Grund ist ctypes der einzige Mechanismus, der für Ironpython und (schließlich, wenn sie es alle arbeiten bekommen) arbeiten jython.

Als jemand anders erwähnt, ist keine Kompilierung erforderlich. Das bedeutet, dass, wenn eine neue Version des DLL oder .so herauskommt, können Sie es einfach fallen in, und diese neue Version laden. Solange die keine der Schnittstellen geändert, es ist ein direkter Ersatz.

Etwas im Auge zu behalten ist, dass SWIG Ziele nur die CPython Umsetzung. Da ctypes auch durch die PyPy und Ironpython-Implementierungen unterstützt wird, kann es sich lohnen, Ihre Module mit ctypes für die Kompatibilität mit dem breiteren Python Ökosystem zu schreiben.

Ich habe SWIG in ihrem Ansatz ein wenig aufgebläht sein (in der Regel nicht nur Python) erwiesen und schwierig zu implementieren, ohne den wunden Punkt des Schreibens Python-Code mit einer expliziten Einstellung überqueren werden SWIG freundlich, anstatt Python sauber gut geschriebenen Code zu schreiben. Es ist meiner Meinung nach, ein viel einfacher Prozess C-Bindungen an C ++ (bei Verwendung von C ++) und dann ctypes verwenden, um eine Schnittstelle zu einer C-Schicht.

zu schreiben

Wenn die Bibliothek, die Sie Anbindung an eine C-Schnittstelle als Teil der Bibliothek, ist ein weiterer Vorteil von ctypes dass Sie keine separate Python-Bindung Bibliothek kompilieren müssen Bibliotheken von Drittanbietern zugreifen. Dies ist besonders schön in eine puren-Python-Lösung zu formulieren, die plattformübergreifende Kompilierung Probleme vermeidet (für den Drittanbieter-Libs auf verschiedene Plattformen angeboten). Mit kompilierten Code in ein Paket, das Sie auf so etwas wie PyPI in einer Cross-Plattform-freundliche Art und Weise ist ein Schmerz implementieren möchten einzubetten; einer meiner irritierenden Punkte über Pakete Python mit SWIG oder der zugrunde liegenden expliziten C-Code ist ihre allgemeine Nichtverfügbarkeit Cross-Plattform. Also bedenken Sie, wenn Sie zur Verfügung Drittanbieter-Bibliotheken mit Cross-Plattform arbeiten und die Entwicklung einer Python-Lösung um sie herum.

Als reales Beispiel, betrachten PyGTK. Diese (glaube ich) verwendet SWIG C-Code als Schnittstelle zu den GTK C Anrufe zu generieren. Ich habe dies für die kürzeste Zeit nur einen echten Schmerzen zu finden, einzurichten und zu verwenden, mit skurrilen ungeradeen Fehlern, wenn Sie nicht Dinge tun, haben in der richtigen Reihenfolge auf Setup und nur im Allgemeinen. Es war so eine frustrierende Erfahrung, und wenn ich mir die interace Definitionen sah von GTK auf dem Netz zur Verfügung gestellt wurde mir klar, was für eine einfache Übung es einen Übersetzer jener Schnittstelle zu Python ctypes Schnittstelle zu schreiben wäre. Ein Projekt namens PyGGI geboren wurde, und an einem Tag konnte ich PyGTK umschreiben ein viel functiona und nützliches Produkt, das sauber auf die GTK C-objektorientierten Schnittstellen übereinstimmt. Und es bedurfte keine Zusammenstellung von C-Code macht es Cross-Plattform-freundlich. (I war tatsächlich nach dem WebKitGTK Schnittstelle, die nicht so plattformübergreifende ist). Ich kann auch bereitstellen leicht PyGGI auf jeder Plattform unterstützt GTK.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top