Python 不同素因子函数的速度
我有这3个素因子函数,我不理解它们在时间复杂度上的差异 这是我开始使用的第一个函数,我想让它更快。我已经有了一个相当快的素数函数,但我认为筛子会更快Python 不同素因子函数的速度,python,performance,list-comprehension,prime-factoring,Python,Performance,List Comprehension,Prime Factoring,我有这3个素因子函数,我不理解它们在时间复杂度上的差异 这是我开始使用的第一个函数,我想让它更快。我已经有了一个相当快的素数函数,但我认为筛子会更快 def is_prime(i): if i <= 1: return False if i <= 3: return True if i%3 == 0 or i%2 == 0: return False return sum((1 for y in xrange(5, int(i**0.5)+1, 6)
def is_prime(i):
if i <= 1: return False
if i <= 3: return True
if i%3 == 0 or i%2 == 0: return False
return sum((1 for y in xrange(5, int(i**0.5)+1, 6) if i%y == 0 or i%(y+2) == 0)) == 0
prime_factors_1 = lambda x: [i for i in range(1,x) if x%i == 0 and is_prime(i)]
我计时并得到以下输出:
prime_factorizations: 1.11333088677
prime_factors_1: 0.0737618142745
prime_factors_2: 10.7310789671
关于这段时间,有几件事我不明白:
- 是因为它只产生不同的主要因素吗
- (分层)列表理解是否天生较慢
[[[factors[r].append(i) for r in xrange(q, n+1, q)] for q in range(i,n,i)] for i in (y for y in xrange(2,n+1) if not factors[y])]
# ^^^^^^^^^^^^^^^^^^^^^
不等同于原始代码中的while
循环,它将q
乘以i
,而不是添加i
。即使你做对了,使用列表理解的副作用也会让人困惑,这与列表理解的目的背道而驰,而且对于你构建的庞大的嵌套非列表来说浪费了空间
什么算法会比我原来的非筛选算法更快
您可以将发现的素数因子划分出来,以避免检查后面的素数因子,并减少需要检查的因子数:
def prime_factors(n):
factors = []
if n % 2 == 0:
factors.append(2)
while n % 2 == 0:
n //= 2
candidate = 3
while candidate * candidate <= n:
if n % candidate == 0:
factors.append(candidate)
while n % candidate == 0:
n //= candidate
candidate += 2
if n != 1:
factors.append(n)
return factors
def基本因子(n):
因子=[]
如果n%2==0:
因素。附加(2)
当n%2==0时:
n/=2
候选人=3
当候选人*候选人
为什么非筛网最快
其他函数做了大量工作来生成您不关心的数字因子
为什么列表理解的筛子要慢得多
因为你搞砸了。本部分:
[[[factors[r].append(i) for r in xrange(q, n+1, q)] for q in range(i,n,i)] for i in (y for y in xrange(2,n+1) if not factors[y])]
# ^^^^^^^^^^^^^^^^^^^^^
不等同于原始代码中的while
循环,它将q
乘以i
,而不是添加i
。即使你做对了,使用列表理解的副作用也会让人困惑,这与列表理解的目的背道而驰,而且对于你构建的庞大的嵌套非列表来说浪费了空间
什么算法会比我原来的非筛选算法更快
您可以将发现的素数因子划分出来,以避免检查后面的素数因子,并减少需要检查的因子数:
def prime_factors(n):
factors = []
if n % 2 == 0:
factors.append(2)
while n % 2 == 0:
n //= 2
candidate = 3
while candidate * candidate <= n:
if n % candidate == 0:
factors.append(candidate)
while n % candidate == 0:
n //= candidate
candidate += 2
if n != 1:
factors.append(n)
return factors
def基本因子(n):
因子=[]
如果n%2==0:
因素。附加(2)
当n%2==0时:
n/=2
候选人=3
而候选者*候选者这个问题可能有一些你想要的答案:。您还可以使用dis.dis
调查每个函数中实际发生的情况,以确定其中一个函数较重的原因。您是如何计时的?对于小数字,我希望更直接的方法更快。@g.d.d.c谢谢!那看起来很有趣useful@TadhgMcDonald Jensen I使用timeit输入1234567如果您发现自己在列表理解中使用append
或其他变异操作,或者忽略返回值,请停止。你在无缘无故地建立一个巨大的额外列表,并使用一个看起来没有变异的结构来产生副作用。你应该使用循环。这个问题可能有你想要的一些答案:。您还可以使用dis.dis
调查每个函数中实际发生的情况,以确定其中一个函数较重的原因。您是如何计时的?对于小数字,我希望更直接的方法更快。@g.d.d.c谢谢!那看起来很有趣useful@TadhgMcDonald Jensen I使用timeit输入1234567如果您发现自己在列表理解中使用append
或其他变异操作,或者忽略返回值,请停止。你在无缘无故地建立一个巨大的额外列表,并使用一个看起来没有变异的结构来产生副作用。你应该使用一个循环。