Embedding im Vergleich

Code-Stücke können hier veröffentlicht werden.
Antworten
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hi,

Mir war grade ein wenig langweilig und ich dachte mir: "Hey, mal sehen wie Embedding funktioniert, wollte ich sowieso schon mal machen".

Beispiel 1 demonstriert Python-Embedding.

Kompiliert wird das ganze mit ``gcc -I/usr/include/python2.6/ -lpython2.6 pyembed.c -o pyembed`` und das resultierende Binary ist 9.9KB bzw 5.3KB nach ``strip`` groß. Das ist ziemlich fair. Was mir weniger gefällt ist, dass man relativ viel mit INCDEF und DECREFs machen muss (in diesem Code scheinbar nicht, da beim erstellen das INCREF implizit ist und DECREF bei ``Py_Finalize``). Dafür ist der Code recht kurz.

Gut, wie sieht das nun woanders aus? Die naheleigende Idee ist die (ehemalige?) offzielle GNU-Skriptsprache zu verwenden, also zu Beispiel 2: Guile-Embedding.

Kompiliert wird es mit ``gcc -Iinclude guileembed.c -o guileembed -Llib -lguile`` (ich habe Guile 1.9.1 lokal in einen Ordner installiert, daher die Include/Lib-Pfade). Raus kommt ein 9.7 KB bzw 5.1 KB großes Binary, das ebenfalls wunderbar funktioniert. Der Code ist relativ klar, ich habe mir aber keine Gedanken gemacht, wie dort Sachen weggeräumt werden. Alles in allem etwas länger, aber die Dokumentation (von Guile 1.8 ) ist ziemlich klar und hat mich von allen drei präsentierten Beispielen am schnellsten ans Ziel geführt.

Schließlich noch ein drittes Beispiel: PLT Scheme Embedding. Das fühlt sich fürchterlich aufwändig an, da man erstmal eine ``base.c`` erstellen muss, mittels ``mzc --c-mods base.c ++lib scheme/base``. Die ist dann gleich mal 1.5 MB groß. Dann erstellt man die verlinkte C-Datei. Ich habe festgestellt, dass man bei PLT die Auswahl zwischen "ignorier den GC" (aka CGC) und "Python C-API-mäßig nur schlimmer" (aka 3m) hat. Und als dritten Punkt "schreibe CGC-Code und lasse 3m-Code draus generieren". Das habe ich dann mal mittels ``bin/mzc --xform pltembed.c`` gemacht. Nach relativ langem warten kam dann eine weitere 2.3 MB große Datei raus (ich nehme an handgeschriebener 3m-Code ist kürzer) die dann kompiliert mit ``gcc -Iinclude/plt -Llib -lmzscheme3m pltembed.3m.c -o pltembed`` immer noch auf 461 KB bzw. 457 KB kommt.

Achja, alle drei Dateien sind natürlich dynamisch gelinkt und benötigen eine libpython, libmzscheme3m oder libguile. Aber der Einstieg ist nicht schwer und an einem Nachmittag zu machen.

Wobei man ja sagen muss: tendentiell neigt man heutzutage eher die eigentliche Applikation in einer Skriptsprache zu schreiben und schnelle Teile auszulagern statt die Skriptsprache für Dinge die flexibel sein sollen einzubetten.

Mag jemand ein Beispiel für Lua basteln? :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Leonidas hat geschrieben:Mag jemand ein Beispiel für Lua basteln? :)
Okay, ich konnte es nicht, lassen: Beispiel 4: Lua Embedding (Lua 5.1). Die API ist etwas seltsam, denn scheinbar kann Lua nicht "1+1" direkt verarbeiten, sondern man muss es an einen Namen binden. Diesen Namen holt man sich dann als den Globals mit ``lua_getfield`` auf den Stack und kann dann diesen Wert auf dem Stack mit ``lua_tointeger`` vom Stack als Integer rausnehmen. Das Binary ist 131 KB bzw 110 KB groß, wird mittels ``gcc -Iinclude luaembed.c -Llib -llua -lm -o luaembed`` kompiliert. Im Gegensatz zu den anderen Embedding-Möglichkeiten linkt es zur C Math Library (die ist aber überall vorhanden) und, was besonders interessant ist, braucht es gar keine liblua -> ``ldd`` zeigt da nichts an, somit hat das Binary keine weiteren nennenswerten Dependencies. Das ist schon ziemlich nett.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten