2011-01-06 6 views
7

Die Python-Dokumentation besagt, dass der Grund, warum cPickle schneller als Pickle ist, dass ersteres in C implementiert ist. Was bedeutet das genau?In Python, warum ist ein Modul in C schneller als ein reines Python-Modul implementiert, und wie schreibe ich ein?

Ich mache ein Modul für fortgeschrittene Mathematik in Python, und einige Berechnungen benötigen eine erhebliche Menge an Zeit. Bedeutet das, dass wenn mein Programm in C implementiert wird, es viel schneller gemacht werden kann?

Ich möchte dieses Modul aus anderen Python-Programmen importieren, genau wie ich cPickle importieren kann.

Können Sie erklären, wie Sie ein Python-Modul in C implementieren?

Antwort

13

Sie können schnell C-Code schreiben und dann in Ihren Python-Skripten verwenden, damit Ihr Programm schneller läuft. [1] http://docs.python.org/extending/index.html#extending-index

ein Beispiel ist Numpy, geschrieben in C (http://numpy.scipy.org/)

Eine typische Anwendung ist die Engpass in C umzusetzen (oder zu verwenden, um eine Bibliothek in C geschrieben, natürlich;)), aufgrund seiner Geschwindigkeit und durch die Art und Weise

[1] python für den verbleibenden Code zu verwenden, deshalb cPickle schneller als Beize ist

edit:

einen Blick auf Pyrex nehmen: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/About.html

‚Pyrex ist eine Sprache, speziell entworfen für das Schreiben von Python-Erweiterung Module. Es ist entworfen, um die Lücke zwischen der schönen, auf hohem Niveau zu überbrücken, leicht zu bedienende Welt von Python und die chaotisch, Low-Level-Welt von C. '

es ist nicht die ‚offizielle‘ Weg aber es kann nützlich sein

+2

+1 Sie sollten eine reine C-Implementierung Ihrer Kernberechnungen mit einer Python-Implementierung vergleichen, die Numpy für das Heavy-Lifting verwendet. Es besteht eine gute Chance, dass die Implementierung von Numpy wettbewerbsfähig sein wird. – divegeek

+1

+1 für Numpy. Es besteht eine sehr gute Chance, dass, wenn Numpy das tut, was Sie wollen, es schneller ist als alles, was Sie schreiben könnten, ohne viel Zeit in die Optimierung des Codes zu investieren. –

6

Wie erwähnt, ist numpy hervorragend für Vektorberechnungen. (Könnte noch besser sein, aber der Kommentar, dass es besser ist als alles, was man ohne Arbeit schreiben könnte, ist definitiv richtig.)

Nicht alles kann leicht vektorisiert werden, wenn Sie also enge innere Schleifen mit vielen haben Funktionsaufrufe (sagen wir einen stark rekursiven Algorithmus) haben Sie immer noch ein paar Optionen: wahrscheinlich ist die populärste Cython, die Ihnen erlaubt, Module und Funktionen in einer Art mit Anmerkungen versehenen Python zu schreiben und C-ähnliche Geschwindigkeit zu bekommen, wenn Sie sie brauchen.

Oder vielleicht wird Ihre Zeit von Bibliotheksaufrufen dominiert, um Eigenwerte zu berechnen oder Matrizen zu berechnen oder spezielle Funktionen zu evaluieren oder wirklich große Ganzzahlen zu teilen - viele von denen das Sage Projekt sehr gut übrigens behandelt, was Sie sind Tun ist mathematischer als reines Knirschen - in diesem Fall spielt die Zeit in Python keine Rolle. Es kommt auf die Details der Art von Zahlen an, die Sie tun.

3

Neben Pyrex/Cython bereits erwähnt, haben Sie andere Alternativen:

Shed Skin: Übersetzt (eine eingeschränkte Teilmenge von) Python zu C++. Kann automatisch eine Erweiterung für Sie generieren.Sie würden eine Erweiterung, dies zu tun (vorausgesetzt, Linux) erstellen:

wget http://shedskin.googlecode.com/files/shedskin-0.7.tgz 
tar -xzf shedskin-0.7.tgz 
# On your code folder: 
PYTHONPATH=/path/to/shedskin-0.7 python shedskin -e yourmodule.py 
# The above generates a Makefile and a yourmodule.h/.cpp pair 
make 
# Now you can "import yourmodule" from Python and check it's from the .so by "print yourmodule.__file__ 

PyPy: Ein schnellen Python, mit einem JIT-Compiler. Sie könnten einfach Ihren Code anstelle von CPython ausführen. Unterstützt jetzt nur Python 2.5, 2.7 Unterstützung bald. Kann enorme Beschleunigung auf mathematischen Code geben. So installieren und starten Sie es (vorausgesetzt, Linux 32-bit):

wget http://pypy.org/download/pypy-1.4.1-linux.tar.bz2 
tar -xjf pypy-1.4.1-linux.tar.bz2 
sudo ln -s /path/to/pypy-1.4.1-linux/bin/pypy /usr/local/bin 
# Then, instead of "python yourprogram.py" you'll just run "pypy yourprogram.py" 

Weave: Hier können Sie write C inline, die kompiliert.

Edit: Wenn Sie wollen, dass wir diese Werkzeuge für Sie und Benchmark laufen, nur posten Sie Ihren Code;)

5

Wenn Sie eine Funktion in Python zu schreiben, ein neues Funktionsobjekt erstellt wird, wird der Funktionscode analysiert und bytecompiled [und gespeichert im "func_code" -Attribut], wenn Sie also diese Funktion aufrufen, liest der Interpreter seinen Bytecode und führt ihn aus.

Wenn Sie die gleiche Funktion in C schreiben und der C/Python-API folgen, um sie in Python verfügbar zu machen, erstellt der Interpreter das Funktionsobjekt, aber diese Funktion hat keinen Bytecode. Wenn der Interpreter einen Aufruf an diese Funktion findet, ruft er die echte C-Funktion auf, also wird er mit "Maschinengeschwindigkeit" und nicht mit "Python-Maschinen" -Geschwindigkeit ausgeführt.

Sie können diese Prüffunktionen in C geschrieben überprüfen:

>>> map.func_code 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'builtin_function_or_method' object has no attribute 'func_code' 
>>> def mymap():pass 
... 
>>> mymap.func_code 
<code object mymap at 0xcfb5b0, file "<stdin>", line 1> 

Um zu verstehen, wie Sie C-Code für Python Verwendung folgen die Führungen in der offiziellen Seite zu schreiben.

Wie auch immer, wenn Sie nur N-dimensionale Array-Berechnungen durchführen, sollte numpy ausreichen.

+0

Mache etwas anderes, das ich nirgendwo im Web finden werde, jedenfalls hat das geholfen, danke! –

Verwandte Themen