続・Pythonの計算を早くするには

最初のコード

wallis_v2.py
```from numpy import *

def f(x):
return sin(pi*x)

product_array = [0 for i in range(10)]

n = 1000000
inv_n = 1.0 / n
for k in range(n):
x = k * inv_n
y = f(x)
z = y
for m in range(10):
product_array[m] += z
z *= y

product = prod(list(map(lambda x: x * inv_n, product_array)))
result = 1.0/product
print(result)
```

```\$ time python3 wallis_v2.py
36722.3621743
python3 wallis_v2.py  8.96s user 0.05s system 99% cpu 9.050 total
```

importの最適化

まず`import`の部分を使用するモジュールに限定します。

```from numpy import prod
from math import sin, pi
```
```\$ time python3 wallis_v2.py
36722.3621743
python3 wallis_v2.py  7.67s user 0.06s system 99% cpu 7.755 total
```

1秒以上早くなりました。

Cythonの使用

pyxファイルへの分割

wallis_v3.py
```import pyximport
pyximport.install()

from integral_lib import integral

print(integral(1000000))
```
integral_lib.pyx
```from numpy import prod
from f import f

def integral(n):
product_array = [0 for i in range(10)]
inv_n = 1.0 / n
for k in range(n):
x = k * inv_n
y = f(x)
z = y
for m in range(10):
product_array[m] += z
z *= y

return 1 / prod(list(map(lambda x: x * inv_n, product_array)))
```
f.pyx
```from math import sin, pi

def f(x):
return sin(pi * x)
```
```\$ time python3 wallis_v3.py
36722.3621743
python3 wallis_v3.py  1.05s user 0.06s system 98% cpu 1.134 total
```

静的型付

f2.pyx
```from math import sin, pi

def f(double x):
cdef:
double res = sin(pi * x)
return res
```
integral_lib2.pyx
```from numpy import prod
from f2 import f

def integral(int n):
product_array = [0.0 for i in range(10)]

cdef:
double inv_n = 1.0 / n
double x,y,z
int k
for k in range(n):
x = k * inv_n
y = f(x)
z = y
for m in range(10):
product_array[m] += z
z *= y

return 1.0 / prod(list(map(lambda x: x * inv_n, product_array)))
```
wallis_v3.py
```from integral_lib2 import integral
```
```\$ time python3 wallis_v3.py
36722.3621743
python3 wallis_v3.py  0.80s user 0.06s system 97% cpu 0.884 total
```

f2.pyx
```from libc.math cimport sin,M_PI

def f(double x):
cdef:
double res = sin(M_PI * x)
return res
```
```\$ time python3 wallis_v3.py
36722.3621743
python3 wallis_v3.py  0.72s user 0.06s system 97% cpu 0.802 total
```

参考

Cython : C との融合による高速化