「エラトステネスの篩」の記事は,ここでも,もう数十回あるんじゃないだろうか。車輪の再発明もいいとこだ。
そして,リストを使わないほうが良いよというのも,何回か書いた。
それ,numpy で書かない?--3--
https://qiita.com/WolfMoon/items/0483ac130684a10cf25e
また,出たが,繰り返し述べる。
リスト,および,リスト内包表記を使うのは,もう,やめよう。
numpy は,遥かに速く,書きやすい。
import time
def sieve_of_eratosthenes(n):
primes = [True] * (n + 1) #リストの生成、全てTrue
primes[0] = primes[1] = False #0と1は素数ではないので除外 FALSE
for i in range(2, int(n**0.5) + 1):#2以上、2から初めてnの平方根まで計算する
if primes[i]:
for j in range(i * i, n + 1, i):
primes[j] = False
return [i for i, is_prime in enumerate(primes) if is_prime]
start = time.perf_counter()
n = 10**9
primes = sieve_of_eratosthenes(n)
end = time.perf_counter()
print('n:',n,'len:', len(primes), ' time:', end - start)
# n: 1000000 len: 78498 time: 0.10331487499934155
# n: 10000000 len: 664579 time: 0.9959860000017215
# n: 100000000 len: 5761455 time: 10.647423709000577
# n: 1000000000 10 分経過するも,終わらず??
numpy で書く。
import time
import numpy as np
def Eratosthenes(n):
""" 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]
start = time.perf_counter()
n = 10**10
primes = Eratosthenes(n)
end = time.perf_counter()
print('n:',n,'len:', len(primes), ' time:', end - start)
# n: 1000000 len: 78498 time: 0.00814820900268387
# n: 10000000 len: 664579 time: 0.05577545899723191
# n: 100000000 len: 5761455 time: 0.6621968749968801
# n: 1000000000 len: 50847534 time: 10.780209208998713
# n: 10000000000 20 分経過するも,終わらず??