瓶颈实际上在于您的
for
循环。Python的
for
循环相对较慢,因此如果您需要迭代一百万个项目,则完全避免它们可以获得很多速度。在这种情况下,这很容易做到。取而代之的是:
for item in range(n):
if ((s1[item])**2 + (s2[item])**2) < 1:
ii = ii + 1
请执行以下操作:
ii = ((s1 ** 2 + s2 ** 2) < 1).sum()
这能够实现是因为numpy
具有内置的支持优化数组操作的功能。循环发生在c
中而不是Python中,所以它会更快。我进行了一个简单的测试,让你可以看到差异:
>>> def estimate_pi_loop(x, y):
... total = 0
... for i in xrange(len(x)):
... if x[i] ** 2 + y[i] ** 2 < 1:
... total += 1
... return total * 4.0 / len(x)
...
>>> def estimate_pi_numpy(x, y):
... return ((x ** 2 + y ** 2) < 1).sum()
...
>>> %timeit estimate_pi_loop(x, y)
1 loops, best of 3: 3.33 s per loop
>>> %timeit estimate_pi_numpy(x, y)
100 loops, best of 3: 10.4 ms per loop
这里有一些可行的操作示例,让您了解它是如何工作的。
将数组平方:
>>> a = numpy.arange(5)
>>> a ** 2
array([ 0, 1, 4, 9, 16])
添加数组:
>>> a + a
array([0, 2, 4, 6, 8])
比较数组:
>>> a > 2
array([False, False, False, True, True], dtype=bool)
布尔值求和:
>>> (a > 2).sum()
2
也许你已经意识到,有更快的方法来估算圆周率,但我必须承认,我一直很欣赏这种方法的简单和有效性。
random.random()
数字呢?但是,正如 @Kevin 指出的那样,这个算法基本上是O(n)
的,因此对于大的n
,对精确实现的任何更改都只会对总运行时间产生最小的影响。 - jonrsharpe