用Python中的对数加速大a循环

用Python中的对数加速大a循环,python,performance,matlab,logarithm,Python,Performance,Matlab,Logarithm,我正在尝试加速以下代码: from math import log from random import random def logtest1(N): tr=0 for i in range(1,N): T= 40 + 10*random() tr += -log(random())/T 我对python相当陌生(来自matlab)。。。同样的代码在python中的运行速度比matlab(和Julia)慢5倍,这引起了我的注意 我尝试使用一个

我正在尝试加速以下代码:

from math import log
from random import random

def logtest1(N):
    tr=0
    for i in range(1,N):
        T= 40 + 10*random()
        tr += -log(random())/T
我对python相当陌生(来自matlab)。。。同样的代码在python中的运行速度比matlab(和Julia)慢5倍,这引起了我的注意

我尝试使用一个numba和一个parakeet包装器,以及numpy函数而不是python函数,但没有得到任何改进

我非常感谢你的帮助。 谢谢


编辑:整个过程是蒙特卡罗模拟,所以N非常大10e6出于测试目的

如果您使用的是Python 2.7x,请立即使用xrange 因此,在2.7中:

def logtest1(N):
    tr=0
    for i in xrange(N):  
        a = random()   # Just generate the random number once
        T= 40 + 10*a
        tr += -log(a)/T

下面是关于为什么xrange更好的一个总结:

如果您使用的是Python 2.7x,请立即使用xrange 因此,在2.7中:

def logtest1(N):
    tr=0
    for i in xrange(N):  
        a = random()   # Just generate the random number once
        T= 40 + 10*a
        tr += -log(a)/T
下面是关于xrange为什么更好的一个总结:

您应该认真研究一下。而且,当你这么做的时候。Numpy是一个针对N维数组数值的速度优化包,而Scipy是一个基于Numpy的科学计算工具的集合

如果使用numpy数组编写函数,则如下所示:

def logtest2(N):
    T = 40. + 10. * np.random.rand(N)
    return np.sum(-1*np.log(np.random.rand(N)) / T)
速度也快得多。使用
N=1000000进行测试时,您的版本的运行时间为500毫秒,而此版本的运行时间为75毫秒。

您应该认真研究一下。而且,当你这么做的时候。Numpy是一个针对N维数组数值的速度优化包,而Scipy是一个基于Numpy的科学计算工具的集合

如果使用numpy数组编写函数,则如下所示:

def logtest2(N):
    T = 40. + 10. * np.random.rand(N)
    return np.sum(-1*np.log(np.random.rand(N)) / T)

速度也快得多。使用
N=1000000进行测试时,您的版本的运行时间为500毫秒,此版本的运行时间为75毫秒。

您可以展示您使用numpy的尝试吗?您可以发布您的numpy代码并尝试使用numba吗?这种类型的循环使用
range
,只需简单的算术运算,正是numba擅长的循环类型。我想可能是使用
math.log
和/或
random.random
会触发一个numba标志,表明它不会尝试jit那些库方法。但是numpy/numba不能加速的说法是不合理的,所以我们需要看到code.BTW,
range(1,N)
运行循环
N-1
次。这是你的本意吗?通过将常量更改为
float
,即0.0、40.0、10.0,可以稍微提高速度。另外,
tr+=-log(random())/T
tr=tr-log(random())/T略慢。但是,与卡斯滕建议的使用numpy相比,使用这些微小变化所带来的速度提升是微不足道的(这就是为什么这是一个评论,而不是一个答案)。不,范围(1,N)不是有意的,它应该是(0,N),感谢您的注意。我尝试了你的建议,得到了改进,使代码比matlab代码慢了4倍(从5倍下降)。当我使用numpy时,我只是用numpy函数替换了log和random函数,但没有使用数组,因为正如我在下面解释的,模拟循环了很多次,试图创建一个大的数组会引发内存错误。你能展示你使用numpy的尝试吗?你能发布你的numpy代码和尝试使用numba吗?这种类型的循环使用
range
,只需简单的算术运算,正是numba擅长的循环类型。我想可能是使用
math.log
和/或
random.random
会触发一个numba标志,表明它不会尝试jit那些库方法。但是numpy/numba不能加速的说法是不合理的,所以我们需要看到code.BTW,
range(1,N)
运行循环
N-1
次。这是你的本意吗?通过将常量更改为
float
,即0.0、40.0、10.0,可以稍微提高速度。另外,
tr+=-log(random())/T
tr=tr-log(random())/T略慢。但是,与卡斯滕建议的使用numpy相比,使用这些微小变化所带来的速度提升是微不足道的(这就是为什么这是一个评论,而不是一个答案)。不,范围(1,N)不是有意的,它应该是(0,N),感谢您的注意。我尝试了你的建议,得到了改进,使代码比matlab代码慢了4倍(从5倍下降)。当我使用numpy时,我只是用numpy函数替换了log和random函数,但没有使用数组,因为正如我在下面解释的,模拟循环了很多次,试图创建一个大的数组会引发内存错误。只生成一次数字会改变分布,不要认为这是故意的。如果不知道你对代码的意图是什么。。。这感觉像是一个有待改进的领域。无论哪种方式,xrange都会做很多事情,而Carsten所写的nympy也会有所帮助。谢谢。使用xrange提高了10%的平均速度,这是相当可观的,但仍然不足以达到Julia速度。不幸的是,在两次计算中使用相同的随机数不是我可以接受的。仅在更改分布后生成该数字,不要认为这是故意的。如果不确切知道您对代码的意图是什么。。。这感觉像是一个有待改进的领域。无论哪种方式,xrange都会做很多事情,而Carsten所写的nympy也会有所帮助。谢谢。使用xrange提高了10%的平均速度,这是相当可观的,但仍然不足以达到Julia速度。不幸的是,在两种计算中使用相同的随机数不是我可以接受的。谢谢,这真的很有帮助,但是矢量化这部分代码是不可能的,因为完整的MC模拟循环了2480368834次,如果我想要更详细的结果,可能会更多。@Esteban分块执行。如果你总是对一百万次跑步进行矢量化,那么你只需要循环2481次。谢谢Carsten。我会尝试这个,如果这是一个新手问题,我道歉,我的领域不是编程,我学到了很多,只是我没有人可以问