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を参考にすると良いかも知れない。 |