随机过程的循环优化

Ale*_*s G 1 python optimization performance

由于我将这段代码调用了1000多次,有没有办法优化这段代码需要1.73秒?

def generate():
    S0    = 0
    T     = 1.
    nt    = 100000
    lbd   = 500.
    mu    = 0
    sigma = 1.

    dt = T/nt
    St  = [S0]  * nt
    sqrtdt = np.sqrt(dt)
    dBt = np.random.normal(0, sqrtdt, nt)

    for k in xrange(1, nt):
        dSt = lbd * (mu - St[k-1]) * dt + sigma * dBt[k]
        St[k] = St[k-1] + dSt
    return St
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 5

您可以挤出更多的工作for-loop,但同时生成所有路径(假设您有足够的内存):

import numpy as np

def generate_orig(T=1., nt=100000, lbd=500., mu=0, sigma=1., S0=0):
    dt = T/nt
    St  = [S0]  * nt
    sqrtdt = np.sqrt(dt)
    dBt = np.random.normal(0, sqrtdt, nt)

    for k in xrange(1, nt):
        dSt = lbd * (mu - St[k-1]) * dt + sigma * dBt[k]
        St[k] = St[k-1] + dSt
    return St

def generate(T=1., nt=100000, lbd=500., mu=0, sigma=1., S0=0, npaths=1):
    dt = T/nt
    St  = np.full((nt, npaths), S0)
    sqrtdt = np.sqrt(dt)
    dBt = np.random.normal(0, sqrtdt, size=(nt, npaths))

    for k in xrange(1, nt):
        dSt = lbd * (mu - St[k-1]) * dt + sigma * dBt[k]
        St[k] = St[k-1] + dSt
    return St
Run Code Online (Sandbox Code Playgroud)

这是100条路径的时间基准.

In [55]: %timeit [generate_orig() for i in xrange(100)]
1 loops, best of 3: 23.6 s per loop

In [56]: %timeit generate(npaths=100)
1 loops, best of 3: 1.97 s per loop
Run Code Online (Sandbox Code Playgroud)

您也可以for-loop通过使用Cython 来提高性能.

  • @Ali:Python循环通常很慢.NumPy试图通过在C/C++/Fortran中执行循环来解决这个问题.您可以通过将尽可能多的工作卸载到NumPy函数调用来获得速度.上面,其中一个瓶颈是`for x in xrange(1,nt)`循环正在执行1000次.如果我们只能做一次`for-loop`怎么办?这就是上面的代码所做的.在`generate_orig`中,`St`是`nt`元素的列表.在`generate`中,`St`是一个`nt`行和`npaths`列的数组. (2认同)