我正在解决leetcode中的编码问题,其中我们应该计算小于非负数n的素数的数量。
这是我的解决方案:
class Solution(object):
def isPrime(self, Number):
return 2 in [Number, 2**Number % Number]
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
count_prime = 0
prime_range = filter(lambda x: x % 2 != 0 and x % 3 != 0 and x % 5 != 0, xrange(n))
for i in prime_range:
if self.isPrime(i):
count_prime += 1
return count_prime
print Solution().countPrimes(499979)
虽然这适用于较小的数字,但是对于较大的数字需要花费大量的时间,而且我不确定哪个部分在我的程序中消耗更多的时间?在这里,我只测试大于100的数字。
任何人都可以帮我找到哪个部分需要更多时间
答案 0 :(得分:2)
任何人都可以帮我找到哪个部分需要更多时间
为什么是, Python可以。简而言之,Python捆绑了cProfile
Python代码的分析器。在其下运行模块会产生以下统计信息:
jim@jim: python -m cProfile tt.py
673
6311 function calls in 0.016 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.016 0.016 tt.py:1(<module>)
1 0.000 0.000 0.000 0.000 tt.py:1(Solution)
4979 0.002 0.000 0.002 0.000 tt.py:12(<lambda>)
1327 0.013 0.000 0.013 0.000 tt.py:3(isPrime)
1 0.000 0.000 0.016 0.016 tt.py:6(countPrimes)
1 0.001 0.001 0.003 0.003 {filter}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
所有这些列are described in the documentation。因此,正如您所看到的,大多数时间实际上花在函数isPrime
上:
1327 0.013 0.000 0.013 0.000 tt.py:3(isPrime)
总共1327
次来电0.013/0.016
次来电C
次。所以,好的,这就是问题所在。
现在,在您发现瓶颈所在之后,您可以尝试寻找优化方法。 大多数时候,只需使用更有效的算法以及合适的数据结构,您就可以获得更好的性能。
如果您想快速加快速度,请考虑查看Cython或Numba等内容。如果那些没有削减它的人会写一个纯粹的div.position-N
扩展名,这可能会更快一些。如果这不能减少,那就放弃吧,因为你对任何事情都不满意。
答案 1 :(得分:0)
你看过eratosthenes筛子了吗?它是寻找素数的经典算法:
Eratosthenes的Sieve是一个简单的算法,可以找到一个给定整数的素数。实现此算法,只允许优化外部循环可以在限制的平方根处停止,内部循环可以从刚刚找到的素数的平方开始。这尤其意味着你不应该通过使用预先计算的轮子进行优化,即不要假设你只需要交叉出奇数(基于2的轮子),数字等于1或5模6(轮子基于2和3),或基于低素数的类似轮子。 http://rosettacode.org/wiki/Sieve_of_Eratosthenes