【发布时间】:2018-09-30 20:25:40
【问题描述】:
#Python 中的这段非常简短的代码试图模拟前 N 个自然数的“埃拉托色尼筛法”,并具有 (0) 脚本长度的约束; (1) 最小化“if 语句”和“for/while 循环”; (2) 在 CPU 时间方面的效率。
import numpy as np
N = 10**5
a = np.array(range(3,N,2))
for j in range(0, int(round(np.sqrt(N),0))):
a[(a!=a[j]) & (a%a[j] == 0)] = 0
a = a[a!=0]
a = [2]+list(a)
在 Intel Core I5 上,它返回第一个中的素数:
- N = 100,000 在 0.03 秒内;
- N = 1,000,000 在 0.63 秒内;
- N = 10,000,000 在 22.2 秒内。
是否有人愿意在上述限制内共享 CPU 时间方面更高效的代码?
【问题讨论】:
-
像你之前的许多人一样,你试图写一个筛子,结果是试除法。
-
@Roberto 筛子的想法是避免分裂,而您的代码却没有。 (一个真正的筛子可以有更短的代码,没有任何比较。)
-
是的,我只是想指出
numpy在性能方面并不是一个好主意。正如 kazemakase 指出的那样,这并不是真正的筛子,因为您反复检查模数。此外,如果您真的想从中榨取性能,(a!=a[j]) & (a%a[j] == 0)是一个非常浪费的操作。 -
这里有很多带有基准的 NumPy 示例:stackoverflow.com/questions/2068372/…
-
在此处特别查看答案:stackoverflow.com/a/3035188/3923281
标签: python numpy sieve-of-eratosthenes