Cython 演習問題
演習1 - 素数判定
(A) 以下のPythonスクリプトを作成し、 primes(1000) の実行に必要な処理時間を測定せよ。
def primes(kmax): p = [0] * kmax result = [] k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] <> 0: i = i + 1 if i == k: p[k] = n k = k + 1 result.append(n) n = n + 1 return result
(B) (A)で作成したスクリプトを primes1.pyxという名前で保存し、Cythonで拡張モジュール primes1 を作成せよ。必要な setup.py ファイルは以下の通りである。また、primes1.primes(1000) の処理時間を測定し、Python版とのパフォーマンスの違いについて考察せよ。
from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("prime1", ["primes1.pyx"])] setup( cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules )
(C) primes1.pyx を以下のように変更して primes1.primes(1000) の処理時間を測定し、(B)との違いについて考察せよ。
cdef extern from "stdlib.h":
ctypedef unsigned long size_t
void *malloc(size_t size)
void free(void *ptr)
def primes(int kmax):
cdef int n, k, i
cdef long *p
p = <long*>malloc(sizeof(long)*kmax)
if not p:
raise MemoryError()
try:
result = []
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] <> 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
result.append(n)
n = n + 1
finally:
free(p)
return result
演習2 - 型定義
(A) 以下のスクリプトを bitset.pyx というファイル名で保存し、 拡張モジュール bitset を作成せよ。また、 BitSet(0x55).setflag(range(10000))の処理速度を測定せよ。
class BitSet: def __init__(self, flag): self.flag = flag def _setbit(self, n): return n | self.flag def setflag(self, nums): ret = [] for n in nums: ret.append(self._setbit(n)) return ret
(B) bitset.pyx を以下のように変更して BitSet(0x55).setflag(range(10000))の処理速度を測定し、 (A) との違いについて考察せよ。
cdef class BitSet:
cdef int flag
def __init__(self, flag):
self.flag = flag
cdef int _setbit(self, int n):
return n | self.flag
def setflag(self, nums):
ret = []
for n in nums:
ret.append(self._setbit(n))
return ret
Cython 演習問題 解説 へ続く