[Python-de] Extension

Bernd Nawothnig Bernd.Nawothnig at t-online.de
Di Mär 27 20:29:37 CEST 2012


On 2012-03-27, Stefan Behnel wrote:
> Bernd Nawothnig, 27.03.2012 17:03:
>> Ein Pythonprogramm ruft eine in C geschriebene Extension mit einem
>> Parameter auf, der aus einer in ein numpy.array konvertierten
>> Python-Liste von Objekten besteht. Das C-Programm nutzt dazu einen
>> Zeiger auf dieses nun eng gepackte Array von Zeigern und wählt durch
>> einen geeigneten Algorithmus aus dieser Objektmenge einige aus, die
>> nun in eine Python-Liste von Python-Listen von Objekten gekapselt
>> zurückgegeben werden. Freigegeben oder verändert wird keines der beim
>> Aufruf der Extension übergebenen Objekte. Die Python-Ergebnisliste
>> wird in C so konstruiert:
>> ...
>> PyObject *r = PyList_New(0);
>> ...
>> static PyObject *VLP_asPyList(VectorlistP *vl)
>> {
>>     PyObject *result = PyList_New(vl->length);
>>     int i;
>> 
>>     for (i=0; i<vl->length; i++)
>>       PyList_SetItem(result, i, Py_BuildValue("O", vl->list[i]->anomaly));
>> //                                                 ^^^^^^^^^^^^^^^^^^^^
>> //                         Zeiger auf eins der ursprünglichen Objekte
>>     return result;
>> }
>> ...
>> PyList_Append(r, VLP_asPyList(&bestResult));
>
> Hier war ein "extend()" gemeint, oder?

Nein, ein PyList_Append, also entsprechend einem python <list>.append().

>> return r;
>
> Zum Vergleich der (mangels umgebendem Code und Daten natürlich ungetestete)
> äquivalente Code in Cython:
>
>   return [ item.anomaly for item in bestResult.list[:bestResult.length] ]
>
> Finde ich hübscher und übersichtlicher.

Im reinen C-Teil verwende ich ja absichtlich _nicht_ die
Python-Datenstrukturen, 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, 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).

static PyObject *VLP_asPyList(VectorlistP *vl)

macht aus meiner C-Variante ganz zum Schluss erst(!) Python, weil ich
das Resultat ja schließlich und letztendlich in Python haben möchte.


Aber viel mehr würde mich interessieren, ob PyList_SetItem und
PyList_Append automatisch den Referenzzähler der eingefügten, bzw.
zugewiesenen Objekte erhöhen. Ich vermute es stark, und die Extension
funktioniert auch problemlos, was aber ja keineswegs eine Garantie auf
Korrektheit ist, weil der GC asynchron zuschlagen kann (und dann
müssen die Referenzzähler korrekt gesetzt sein). Und deswegen wüsste
ich es gerne explizit.

Kann mir da einer was zu sagen?




Bernd

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


Mehr Informationen über die Mailingliste python-de