Seite 1 von 1
ByteCode erzeugen mit compile() und in DB cachen...
Verfasst: Montag 17. Oktober 2005, 09:07
von jens
Der
Umbau von SpyTee ging einfacher als ich dachte. Nun wollte ich weiter gehen und nicht den nackten Python-Code in die DB schreiben sondern diesen schon mal mit
compile() compilieren.
Das gelingt mir spontan aber nicht:
Code: Alles auswählen
code = """def displayself(tpldata):
page=[]
page.append('<table border=0 cellpadding=0 cellspacing=0>')
if tpldata.has_key('colorrow'):
for item_colorrow in tpldata['colorrow']:
page.append(' <tr><td width="10%%">%s</td>' %(item_colorrow.get('color','')))
if item_colorrow.has_key('colorcol'):
for item_colorcol in item_colorrow['colorcol']:
page.append(' <td bgcolor="%s"> </td>' %(item_colorcol.get('code','')))
page.append(' </tr>')
page.append(' </table>')
return page"""
template_pyc = compile(code, "<string>", 'exec')
print template_pyc
Ich erhalte dann:
<code object ? at 009D6860, file "<string>", line 1>
Und ich dachte ich erhalte somit einen Binär-Bytecode?!?! Das code-objekt hat auch keine brauchbaren Methoden:
- __class__
__cmp__
__delattr__
__doc__
__getattribute__
__hash__
__init__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__str__
co_argcount
co_cellvars
co_code
co_consts
co_filename
co_firstlineno
co_flags
co_freevars
co_lnotab
co_name
co_names
co_nlocals
co_stacksize
co_varnames
Verfasst: Montag 17. Oktober 2005, 09:23
von jens
Lösung gefunden in den sourcen von
py_compile.py
Es gibt das
marshal modul (Internal Python object serialization), welches eine dumps()-Methode hat. So geht's dann:
Code: Alles auswählen
import marshal
code = """def displayself(tpldata):
page=[]
page.append('<table border=0 cellpadding=0 cellspacing=0>')
if tpldata.has_key('colorrow'):
for item_colorrow in tpldata['colorrow']:
page.append(' <tr><td width="10%%">%s</td>' %(item_colorrow.get('color','')))
if item_colorrow.has_key('colorcol'):
for item_colorcol in item_colorrow['colorcol']:
page.append(' <td bgcolor="%s"> </td>' %(item_colorcol.get('code','')))
page.append(' </tr>')
page.append(' </table>')
return page"""
template_pyc = compile(code, "<string>", 'exec')
print template_pyc
print "-"*80
print marshal.dumps(template_pyc)
print "-"*80
EDIT: Nun hab ich nur das Problem, das ich den code so nicht ausführen kann

Bei einem
exec template_pyc gibt's den Fehler:
Verfasst: Montag 17. Oktober 2005, 09:37
von jens
Aha... So geht's:
Code: Alles auswählen
import imp, marshal
code = """print 'test1'
print 'test2'"""
template_pyc = compile(code, "<string>", 'exec')
print template_pyc
byte_code = marshal.dumps(template_pyc)
exec marshal.loads(byte_code)
Nun ist nur die Frage ob es überhaupt schneller geht, als Python-Code ohne compilieren direkt mit exec ausführen zu lassen?!?!
Verfasst: Montag 17. Oktober 2005, 15:32
von Leonidas
Qualifiziert sich IMHO für Premature Optimalization.
Verfasst: Montag 17. Oktober 2005, 15:42
von jens
Was willst du mir jetzt damit sagen???
Verfasst: Montag 17. Oktober 2005, 16:03
von Leonidas
jens hat geschrieben:Was willst du mir jetzt damit sagen???
Das du aus einer Mücke einen Elefanten machst. Es geht darum, dass du ein Templating brauchst. Da stimme ich dir zu. Dann bist du aus heiterem Himmel auf die Idee gekommen, dass es zu langsam sein
könnte, ohne dass irgendwo ein tatsächliches Problem ist. Also willst du Templates kompilieren, weil sie schneller sein könnten. Somit hast du dir ein Problem geschaffen: wie kompiliert man Templates? Und was bringt dir so eine Kompilation? Es ist schneller. Aber fällt das im Moment ins Gewicht: ich würde mal auf Nein tippen. Du implementiertst also momentan unnötige Features, vor allem da du dir ja auch schon überlegt hast, welches Templating-System ausreichend schnell ist.
Und ich könnte mir vorstellen, dass der Aufwand Code erst aus einer Datenbank zu holen und dann mit exec zu starten größer ist, als der Vorteil, den kompilierte Templates überhaupt bieten.
Verfasst: Montag 17. Oktober 2005, 16:20
von jens
Ich denke du hast meine EDIT noch nicht gesehen, deswegen pack ich das hier nochmal drunter:
Ich hab gerade mal geschaut, wielange denn überhaupt das compilieren eines Templates dauert... Und es geht bei spytee und simpleTAL in Windeseile. Ein Caching lohnt sich bei mir nicht... Vielleicht wenn man Komplexe XML-Daten erzeugen will und das Template risen groß ist, vielleicht...
Auf die Idee bin ich eigentlich durch spytee gekommen, weil es halt immer Templates compiliert und als Dateien (echte Python-Skripte) abspeichert/cached. Das hätte ich so nicht verwenden können, weil WebServer/CGI/Datei_schreiben keine gute Kombination ist

Verfasst: Montag 17. Oktober 2005, 17:00
von Leonidas
jens hat geschrieben:Ich hab gerade mal geschaut, wielange denn überhaupt das compilieren eines Templates dauert... Und es geht bei spytee und simpleTAL in Windeseile. Ein Caching lohnt sich bei mir nicht... Vielleicht wenn man Komplexe XML-Daten erzeugen will und das Template risen groß ist, vielleicht...
Ja, eben. Genau das habe ich vermutet.
jens hat geschrieben:Auf die Idee bin ich eigentlich durch spytee gekommen, weil es halt immer Templates compiliert und als Dateien (echte Python-Skripte) abspeichert/cached. Das hätte ich so nicht verwenden können, weil WebServer/CGI/Datei_schreiben keine gute Kombination ist

Ich weiß, Kid macht exakt das gleiche, es erstellt aus Kid-Dateien Python Bytecode. Wobei das mit dem Datei schreiben manchmal auch ausreichend gut funktioniert, wie
Dokuwiki beweist. Ich habe es eingerichtet, es funktioniert recht gut. Die Berechtigungen sind zwar (leider) so, dass alle schreiben dürfen, aber das ist bei einem Wiki ja sowieso recht ok.
Verfasst: Montag 17. Oktober 2005, 18:22
von jens
Leonidas hat geschrieben:Ich weiß, Kid macht exakt das gleiche, es erstellt aus Kid-Dateien Python Bytecode. Wobei das mit dem Datei schreiben manchmal auch ausreichend gut funktioniert, wie
Dokuwiki beweist. Ich habe es eingerichtet, es funktioniert recht gut. Die Berechtigungen sind zwar (leider) so, dass alle schreiben dürfen, aber das ist bei einem Wiki ja sowieso recht ok.
Hm! Demnach lohnt sich das Caching also doch? Zumindest in machen Fällen. IMHO wenn das Template eine gewisse komplexität übersteigt... Denn Dateien schreiben/lesen brauch schließlich auch eine gewisse Zeit!
Nun fällt mir wieder was ein: In meinem Falle liegt das Template sowieso in der SQL-DB. Also ist es nicht langsamer, wenn ich eine gecachte Version holen würde!
Wie auch immer... Ich werd es aber erstmal ohne caching umsetzten, es aber mal im hinterkopf behalten, damit man es später evtl. doch noch einbauen kann. z.Z. weiß ich sowieso noch nicht recht, wie ich simpleTAL richtig integrieren kann
