それ,numpy で書かない?--3--
Python ではリストがよく使われる。また,for ループが遅いのでリストに特化したリスト内包表記も推奨されることが多い。
それなりの根拠があるからではあるが...
課題:エラトステネスの篩を使って $n$ 以下の素数のリストを得る。
from time import time
import numpy as np
import matplotlib.pyplot as plt
n = 100000
trial = 500
以下のプログラムは,この次に示す numpy によるプログラムをリストを使うように書換えたものである。
def sieve1(n):
tbl = [True] * (n + 1)
tbl[0:2] = [False, False]
for i in range(2, n + 1):
if tbl[i]:
for j in range(i * i, n + 1, i):
tbl[j] = False
return [i for i, x in enumerate(tbl) if x]
primes = sieve1(n)
print(f"Number of primes is {len(primes)}.")
times = []
for i in range(trial):
s = time()
sieve1(n)
times.append(time() - s)
print(f"Mean execution time = {sum(times)/trial:.5g}")
Number of primes is 9592.
Mean execution time = 0.0085938
リストは一切使わない。結果の保存も numyp.ndarray を使う。
def sieve2(n):
tbl = np.ones(n+1, dtype=bool)
tbl[0:2] = False
for i in range(2, int(np.sqrt(n))+1):
if tbl[i]:
tbl[i*i::i] = False
return np.arange(n+1)[tbl]
primes = sieve2(n)
print(f"Number of primes is {len(primes)}.")
times = np.zeros(trial)
for i in range(trial):
s = time()
sieve2(n)
times[i] = time() - s
print(f"Mean execution time = {np.mean(times):.5g}")
Number of primes is 9592.
Mean execution time = 0.00028925
ほぼ 30 倍速である。