4. 拡張モジュールのめんどくささ
4
C/C++が必要
/* 一般的なC言語の例 */
int
i;main(){for(;i["]<i;++i){-‐-‐
i;}"];read('-‐'-‐'-‐',i+++"hell
o,
world!n",'/'/'/'));}read(j,i,p)
{write(j/p+p,i-‐-‐-‐j,i/i);}
The International Obfuscated C Code Contest
http://www.ioccc.org/1984/anonymous.c
10. Pythonの構文で
C言語と同じ処理を書ける
10
/*
C言語 */
void
spam()
{
void
*p
=
malloc(100);
if
(!p)
{
return;
}
if
(!ham())
{
goto
exit;
}
egg();
exit:
free(p);
}
#
Cython
def
spam():
cdef
void
*p
=
malloc(100)
if
p:
try:
if
not
ham():
return
egg()
finally:
free(p)
11. Cythonの文法
11
基本は
Python2 とほぼ同じ!
def
qsort(L):
if
len(L)
<=
1:
return
L
return
(
qsort([lt
for
lt
in
L[1:]
if
lt
<
L[0]])
+
[L[0]]
+
qsort(
[ge
for
ge
in
L[1:]
if
ge
>=
L[0]]))
http://code.activestate.com/recipes/66473-just-for-fun-quicksort-in-3-lines/
22. GIL制御
22
言語としてGILを
サポート
p GIL: Global Interpreter Lock
p Pythonスクリプトが、複数のス
レッドで同時に実行されないよう
に制御する仕組み
p PythonのC APIを使わない処理
の間は、GILを開放すると並列
処理の効率が向上するケースも
with
nogil:
#GILを開放し、他のスレッド
#でPython実行を許可する
f
=
fopen(fname,"w")
…
23. C++サポート
23
from
collections
import
defaultdict
def
freq(values):
#
要素に、同じ値が何個あるか
#
数え上げる
d
=
defaultdict(int)
for
v
in
values:
d[v]
+=
1
#
distutils:
language
=
c++
from
libcpp.map
cimport
map
def
freq(list
values):
#
std::map を使用
cdef
map[int,
int]
d
cdef
int
v
for
v
in
values:
d[v]
+=
1
Distutils:で、C++
ファイルの生成を指示
36. Cの関数を定義
36
cdef
int
c_tak(int
x,
int
y,
int
z):
if
x
<=
y:
return
z
return
c_tak(
c_tak(x-‐1,
y,
z),
c_tak(y-‐1,
z,
x),
c_tak(z-‐1,
x,
y))
def
tak(x,
y,
z):
return
c_tak(x,
y,
z)
37. 37
Python版
$ python -m timeit -s "import tak" "tak.tak(18, 9, 0)"
10 loops, best of 3: 2.74 sec per loop
Cython版
$ python -m timeit -s "import tak" "tak.tak(18, 9, 0)"
10 loops, best of 3: 1.47 sec per loop
Cython(cdef)版
$ python -m timeit -s "import tak" "tak.tak(18, 9, 0)"
10 loops, best of 3: 36.9 msec per loop