python - Python大整数性能
问题描述
我想用 python 编写一个素数生成器——我只在 C 和 Java 中做过。我做了以下。我使用整数位图作为数组。算法的性能应该会提高nlog(log(n))
,但随着问题规模的增加,我看到成本/时间呈指数级n
增长。当整数变得比实际更大时,这是我没有看到或不了解python的明显吗?我正在使用 python-3.8.3。
def countPrimes(n):
if n < 3:
return []
arr = (1 << (n-1)) - 2
for i in range(2, n):
selector = 1 << (i - 1)
if (selector & arr) == 0:
continue
# We have a prime
composite = selector
while (composite := composite << i) < arr:
arr = arr & (~composite)
primes = []
for i in range(n):
if (arr >> i) & 1 == 1:
primes.append(i+1)
return primes
对我的运行时的一些分析:
y = nlog(log(n))
(较陡的红线)和y = x
(较不陡峭的蓝线)的图:
我通常不会使用大小超过 uint64 的整数,因为 python 允许无限大小的整数,而我只是在测试,我使用了上述方法。正如我所说,我试图理解为什么算法时间随着问题的大小呈指数增长n
。
解决方案
我使用整数位图作为数组
那是极其昂贵的。Python int 是不可变的。每次你想要切换一点时,你都在构建一个全新的巨大 int。
您还需要构建其他巨型整数来访问您感兴趣的单个位 - 例如,即使您只对 1 位感兴趣,composite
它们~composite
也是巨大的。arr = arr & (~composite)
使用实际的可变序列类型。也许是一个列表,也许是一个 NumPy 数组,也许是 PyPI 的一些位向量类型,但不要使用int
.
推荐阅读
- python - 无法通过 .gitignore 排除 Pipfile 和 Pipfile.lock
- r - 为什么 stargazer 会为我的 lm 回归输出提供一个输出表,但在我使用 lm_robust() 时却没有?
- postgresql - 为什么我的 postgresql 函数插入回滚?
- react-native - 使用 react-navigation 和 redux 实现身份验证流程
- haskell - 为 ADT 派生显示实例不适用于更高种类的类型族
- delphi - How to know how many tasks are already completed?
- visual-studio - 我可以在 AnkhSvn 构建中替换 TurtleTasks
- html - 将删除线元素保存到待办事项列表的本地存储
- javascript - 为什么这个 Ajax ResponseText 是空的?
- git - 为什么 Gitkraken 在大仓库中不显示任何日志?