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 演習問題 解説 へ続く