python - 为什么这些优化看起来明显变慢了?
问题描述
我正在学习 Python(我有一些其他语言的背景,尤其是 C 等),并且我正在尝试编写一些简单的函数来加强我在 Python 教程中所读到的内容。特别是,这是我对确定数字是否为合数的函数的尝试:
def isComposite(n):
"""Straight loop."""
for x in range(2, int(math.sqrt(n)) + 1):
if n % x == 0:
return x
return False
_PrimeList = [2]
def isCompPL(n):
"""Recursive version."""
for x in _PrimeList:
if n % x == 0:
if n == x:
return False
return x
for x in range(_PrimeList[-1], int(math.sqrt(n)) + 1):
if not isCompPL(x):
if x > _PrimeList[-1]:
_PrimeList.append(x)
if n % x == 0:
return x
return False
def isCompSR(n):
"""Serialized recursive version."""
l = [n]
while (math.sqrt(l[0]) > _PrimeList[-1]):
l.insert(0, int(math.sqrt(l[0])))
l.insert(0, _PrimeList[-1] + 1)
while (len(l) > 2):
q = l.pop([0])
for x in range(q, l[0]):
for y in _PrimeList:
if x % y == 0:
break
else:
_PrimeList.append(x)
return isCompPL(n)
isComposite(n)
比任何一个isCompPL(n)
或开始isCompSR(n)
时都快几个数量级。当包含直到 的平方根的所有素数时,两者和都赶上 并且可能比 快,但不是很明显。更令我震惊的是,如果我调用,后续调用仍然比调用慢得多,第一次调用后没有清除。_PrimeList
[2]
_PrimeList
n
isCompPL(n)
isCompSR(n)
isComposite(n)
isCompSR(511111111111)
isCompSR(1111111111111)
isComposite(1111111111111)
_PrimeList
isCompSR
Python中的列表操作是否隐藏了一些东西,使这些尝试在优化方面不成功,或者只是我添加了很多额外的主要测试并且我需要以某种方式减少那部分?
解决方案
两位主要评论者(@alexis、@juanpa.arrivillaga)对我编写的代码都有正确的评估(评估太多数字,以低效的方式使用列表数据类型),并且在两个方面都进行了改进,更新了“序列化递归”功能总体上要快得多,并且_PrimeList
在初始化时比“直接循环”版本快得多。当前版本isCompSR(n)
如下所示:
def isCompSR(n):
"""Serialized recursive version."""
for x in _PrimeList:
if n % x == 0:
return x
l = [n]
while (math.sqrt(l[-1]) > _PrimeList[-1]):
l.append(int(math.sqrt(l[-1])))
l.append(_PrimeList[-1] + 1)
while (len(l) > 2):
q = l.pop()
for x in range(q, l[-1]):
if n % x == 0:
return x
for y in _PrimeList:
if x % y == 0:
break
else:
_PrimeList.append(x)
return False
请注意,此代码现在将在第一个除数处“退出”,n
而不是像以前一样继续处理所有数字math.sqrt(n)
。此外,l
现在通过调用.append
and.pop()
而不是在开头插入和弹出来更合适地使用列表。
推荐阅读
- android - Flutter:主从布局中的自定义 Appbar、浮动操作按钮和 BottomSheet
- functional-programming - SICP 3.6 - 兰德过程和局部状态变量
- javascript - Mocha 连接到错误的 javascript 文件
- javascript - 如何在 React 或 create-react-app 中列出源文件夹内容?
- php - 是否有用于 PHP 的 PostgreSQL SQL 查询字符串解析器?
- mysql - 如何从 Node.js 将汉字插入 MySQL 数据库?
- python-3.7 - 不启动 Python Django ver 3.7.1 django ver 3.0.4
- php - 使 Avatar 也成为超链接
- python - 单击下拉菜单中的所有组合并在 Selenium + Python 中打印文本结果:等待功能不起作用
- javascript - JavaScript“keydown”工作不正确