如何提高Python中估算'Pi'的性能
为了估计如何提高Python中估算'Pi'的性能,python,performance,pi,Python,Performance,Pi,为了估计Pi的值,我用Python编写了以下代码。它被称为方法。显然,通过增加样本数,代码会变慢,我假设代码中最慢的部分在采样部分。 我怎样才能使它更快 from __future__ import division import numpy as np a = 1 n = 1000000 s1 = np.random.uniform(0,a,n) s2 = np.random.uniform(0,a,n) ii=0 jj=0 for item in range(n): if (
Pi
的值,我用Python编写了以下代码。它被称为方法。显然,通过增加样本数,代码会变慢,我假设代码中最慢的部分在采样部分。
我怎样才能使它更快
from __future__ import division
import numpy as np
a = 1
n = 1000000
s1 = np.random.uniform(0,a,n)
s2 = np.random.uniform(0,a,n)
ii=0
jj=0
for item in range(n):
if ((s1[item])**2 + (s2[item])**2) < 1:
ii = ii + 1
print float(ii*4/(n))
来自未来进口部的
将numpy作为np导入
a=1
n=1000000
s1=np.随机均匀(0,a,n)
s2=np.随机均匀(0,a,n)
ii=0
jj=0
对于范围(n)中的项目:
如果((s1[项目]**2+(s2[项目]**2)<1:
ii=ii+1
打印浮动(ii*4/(n))
您是否建议使用其他(可能更快的)代码?这里的瓶颈实际上是您的
for
循环。Pythonfor
循环相对较慢,因此如果需要迭代一百万个项目,可以通过完全避免这些项目来提高速度。在这种情况下,这很容易。与此相反:
for item in range(n):
if ((s1[item])**2 + (s2[item])**2) < 1:
ii = ii + 1
下面是一些可能的操作类型的示例,以便您了解其工作原理
对数组进行平方运算:
>>> 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 + a
array([0, 2, 4, 6, 8])
>>> a > 2
array([False, False, False, True, True], dtype=bool)
布尔值求和:
>>> (a > 2).sum()
2
正如您可能意识到的,有更快的方法来估计Pi,但我承认我一直很欣赏这种方法的简单性和有效性 您已经分配了numpy数组,因此应该利用这些数组
for item in range(n):
if ((s1[item])**2 + (s2[item])**2) < 1:
ii = ii + 1
范围(n)中的项目的:
如果((s1[项目]**2+(s2[项目]**2)<1:
ii=ii+1
变成
s1sqr = s1*s1
s2sqr = s2*s2
s_sum = s1sqr + s2sqr
s_sum_bool = s_sum < 1
ii = s_sum_bool.sum()
print float(ii*4/(n))
s1sqr=s1*s1
s2sqr=s2*s2
s_和=s1sqr+s2sqr
s_sum_bool=s_sum<1
ii=s_sum_bool.sum()
打印浮动(ii*4/(n))
将数组平方,求和,检查和是否小于1,然后将布尔值求和(false=0,true=1),得到满足条件的总数。我对senderle的答案进行了投票,但如果您不想对代码进行太多更改: 是为此目的而设计的图书馆 只需将算法定义为函数,并添加
@jit
装饰器:
from __future__ import division
import numpy as np
from numba import jit
a = 1
n = 1000000
s1 = np.random.uniform(0,a,n)
s2 = np.random.uniform(0,a,n)
@jit
def estimate_pi(s1, s2):
ii = 0
for item in range(n):
if ((s1[item])**2 + (s2[item])**2) < 1:
ii = ii + 1
return float(ii*4/(n))
print estimate_pi(s1, s2)
来自未来进口部的
将numpy作为np导入
从numba导入jit
a=1
n=1000000
s1=np.随机均匀(0,a,n)
s2=np.随机均匀(0,a,n)
@准时制
def估计值_pi(s1、s2):
ii=0
对于范围(n)中的项目:
如果((s1[项目]**2+(s2[项目]**2)<1:
ii=ii+1
返回浮动(ii*4/(n))
打印估价单(s1、s2)
在我的笔记本电脑上,
n=100000000
的加速比大约是20倍,而n=1000000
的加速比大约是3倍。你为什么要计算这个呢?这已经做了一千次了(例如,从文件中读取,或硬编码)。速度慢是算法固有的——每次你想要多一位数的精度,运行时间就会增加10倍。查看更快的方法。是否有任何理由在前面构建两个阵列?为什么不在循环中获取两个random.random()
数字?然而,正如@Kevin所指出的,该算法基本上是O(n)
,因此对于大型n
,对精确实现的任何更改都只会对整个运行时产生极小的影响。@Caramiriel不要问“为什么”。问‘为什么不?’学习算法的工作原理、学校、个人经历和乐趣都是原因。@Caramiriel我知道这已经做了很多次了,尽管我只是出于教育目的使用它。谢谢