Есть ли способ сделать Python код случайной суммы быстрее в Cython? - PullRequest
2 голосов
/ 06 апреля 2020

Я написал фрагмент кода, который dr aws случайных чисел из равномерного распределения, суммирует их, пока не достигнет числа L = x. Я пытался оптимизировать его с помощью Cython, но я хотел бы получить какие-либо предложения о том, как его можно оптимизировать, так как он будет вызываться для больших значений L, поэтому это займет довольно много времени. Это код, который я написал в Jupyter до сих пор

%%cython
import numpy as np
cimport numpy 
import numpy.random

def f(int L):
    cdef double r=0
    cdef int i=0
    cdef float theta
    while r<=L:
        theta=np.random.uniform(0, 2*np.pi, size = None)
        r+=np.cos(theta)
        i+=1    
    return i

Я бы хотел максимально ускорить его

1 Ответ

1 голос
/ 06 апреля 2020

Один из способов ускорить это без использования Cython - это реже вызывать np.random.uniform. Стоимость вызова этой функции и возврата 1 значения против 100 000 значений незначительна, вызов и возврат 1000 значений против вызова 1000 раз дает огромную экономию времени:

def call1000():
    return [np.random.uniform(0, 2*np.pi, size = None) for i in range(1000)]

%timeit call1000()
762 µs ± 3.11 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.random.uniform(0, 2*np.pi, size = 1000)
10.8 µs ± 13.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Вы можете реализовать это и убедиться, что вы не не исчерпайте ценности, делая что-то вроде этого:

def f(L):
    r = 0
    i = 0
    j = 0
    theta = np.random.uniform(0, 2*np.pi, size = 100000)
    while r<=L:
        if j == len(theta):
            j=0
            theta=np.random.uniform(0, 2*np.pi, size = 100000)
        r+=np.cos(theta[j])
        i+=1    
    return i
...