Один из способов ускорить это без использования 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