0
1

それ,numpy で書かない?--7-- いや,もうリストやめよぅ

Posted at

「エラトステネスの篩」の記事は,ここでも,もう数十回あるんじゃないだろうか。車輪の再発明もいいとこだ。
そして,リストを使わないほうが良いよというのも,何回か書いた。

それ,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 分経過するも,終わらず??
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1