|
Pythonっぽい文法で、Cを書き出すってPyRexって言うPythonパッケージ。 例えば、 cdef extern int strlen(char *c)
def hello_world(message):
print message,get_len(message)
cdef int get_len(char *message):
return strlen(message)
みたいな書き方で、C言語のソースをはき出してくれる。 はき出されるコードは /* "/home/shibacow/prog/python/pyrex/hello_world2.pyx":5 */
__pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_get_num); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; goto
__pyx_L1;}
__pyx_2 = PyInt_FromLong(strlen(__pyx_v_message)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; goto
__pyx_L1;}
__pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; goto __pyx_L1;}
PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
__pyx_2 = 0;
__pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; goto __
pyx_L1;}
Py_DECREF(__pyx_1); __pyx_1 = 0;
Py_DECREF(__pyx_3); __pyx_3 = 0;
__pyx_4 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; goto __pyx_L1;}
Py_DECREF(__pyx_2); __pyx_2 = 0;
__pyx_r = __pyx_4;
goto __pyx_L0;
ていう感じになる。 $pyrexc hello_world.pyx ってすると、hello_world.cが出来上がる。 setup.py
from distutils.core import setup
from distutils.extension import Extension
from Pyrex.Distutils import build_ext
import glob, sys
setup(name = 'hello_world',ext_modules=[Extension("hello_world",["hello_world.pyx"]),],cmdclass = {'build_ext': build_ext})
って言うsetup.pyを用意して、 $python setup.py build $su #python setup.py install でsite-packagesに導入できる。 使い方は、 >>> from hello_world import hello_world
>>> hello_world('hoge')
hoge 4
>>> hello_world('foobar')
foobar 6
>>>
という感じになる。 qsortで大体10倍くらい速くなった。素敵。どうしても速度が気になる個所だけCで書いて、後はpythonで書くと言うのが現実的な気がする。 このPDFを参考にすると良いかも知れない。 |