[Python-de] Extension

Bernd Nawothnig Bernd.Nawothnig at t-online.de
So Apr 1 11:29:03 CEST 2012


On 2012-03-28, Stefan Behnel wrote:
>> Im reinen C-Teil verwende ich ja absichtlich _nicht_ die
>> Python-Datenstrukturen
>
> Hatte ich auch so verstanden. Der Code oben (deiner und meiner) dient nur
> der Konvertierung des Ergebnisses von C nach Python.
>
> Der Code, den Cython generiert, hat nur minimal höheren Aufwand als dein
> handgeschriebener - er erzeugt die ursprüngliche Liste nämlich momentan
> nicht mit der finalen Länge. Und das auch nur deshalb, weil ich immer noch
> keine Zeit gefunden habe, die bekannte Länge der Ergebnisliste aus dem
> Iterator durchzuschleifen. Sprich: mit ein bisschen zusätzlichem Aufwand
> würde Cython sogar identischen Code generieren, ohne deinen ganzen C
> Eiertanz oben.
>
> Allerdings würde es mich überraschen, wenn der Geschwindigkeitsunterschied
> jetzt schon sehr auffällig wäre. Der eher meistens vernachlässigbar, weil
> die Konvertierung der Listeneinträge normalerweise deutlich stärker zu
> Buche schlägt als die Vergößerung der Liste, die meistens ohnehin von der
> Speicherverwaltung aufgefangen wird.

Es geht bei der ganzen Sache um einen rein numerischen Algorithmus,
und da ist Python nun mal prinziell weniger gut für geeignet, weil
dort alles Objekte sind, für _jede_ Berechnung also erst die
"Nutzlast" aus dem Objekt geholt werden muss. Das ist zwar sehr schön
für die Allroundverwendung (also mehr als 99% der real anfallenden
Fälle, s.u.), aber ein klarer Nachteil bei einer so speziellen
Geschichte. Und weil es eben reine Berechnungen sind, sieht der C-Code
auch kaum weniger übersichtlich aus als in Python. Ich gewinne also
durch Verwendung von Python an der Stelle nichts, es wird nur
langsamer.

Anders siehst das z.B. aus, wenn man mit Datenbanken arbeitet, und
möchte SQL auf die Applikationssprache abbilden. Ich verwende z.Z. auf
der Arbeit Java und da ist das schon ein ganz schöner Eiertanz, wenn
man Java double oder int einfach nur in ein Dictionary einfügen
möchte oder etwa statt int SQL NULL bekommt. Alleine die Menge der
try/catch/throws bläht den Code gegenüber Python ebenso gewaltig wie
vollkommen unnötig auf. In Python (etwa zusammen mit psycopg2) erhält
man dann ein sauberes und eindeutiges None und kein integer 0!.
Alleine auf die Idee zu kommen, SQL NULL::int auf 0 ist mappen, ist
krank und hochgradig fehlerträchtig. Und selbstverständlich kann ich
in Python auch Ganzzahlen in ein Dictionary einfügen - ohne erst eine
Wrapper-Klasse dafür anlegen zu müssen.

>>, weil ich eben schneller werden will (was auch
>> weit über alle Erwartungen geklappt hat ;-). Gerade die dauernden
>> appends, bzw. auch Listcomprehensions, wie Du sie erwähntest (ich
>> weiß, die sind sehr elegant und ich verwende die auch sehr gerne),
>> holen sich jedes Mal Speicher vom Heap, der praktisch dann gleich
>> wieder freigegeben werden kann

> Äh, bitte wie? Warum sollten sie das denn tun?

Wenn man Listen so erzeugt, wird jedesmal Speicher vom Heap geholt und
der alte Speicherbereich kann freigegeben werden.

>> während der mir sehr wohl bekannte
>> wirkliche Speicherverbrauch dieses Algorithmus _sehr_ überschaubar
>> ist. Entsprechend dramatisch war dann auch der Speedup (mehr als
>> Faktor 1000).
>
> Aber nur gegenüber CPython, richtig?

Ja. Und ich muss auch sagen, dass ich bei der Umstellung diverse
Schwächen des Python-Codes erkannt, und dann natürlich in C
entsprechend geändert habe. So wurden z.B. in in der Pythonversion
zwecks Abstandsberechnungen in der inneren Schleife jeweils
Quadratwurzeln gezogen. Allerdings fiel mir jetzt auf, dass ich ja
ebenso die Quadrate der Abstände vergleichen kann (es interessiert
hier nur ein <=, kein ==), die eh einen Schritt vorher anfallen.

Wenn man das jetzt in Python ebenfalls umstellen würde, wozu ich aber
nun keine Lust habe, sähe das Ergebnis mit Sicherheit nicht ganz so
schlecht für Python aus.

[...]

> Schau in die Doku (wie Dietmar es für dich getan hat). Unnötig zu sagen,
> dass Cython dir diese Details abnimmt.

Ich werde mir Cython wohl ebenfalls mal anschauen müssen :)




Bernd

-- 
"Die Antisemiten vergeben es den Juden nicht, dass die Juden Geist
haben - und Geld." [Friedrich Nietzsche]


Mehr Informationen über die Mailingliste python-de