I have written an algorithm to do any number monte carlo simulations for a given system.
When I do 10,000 simulations each of length 254, my python+numpy routine takes about 51 seconds to run.
When I test the same algorithm under my cython+numpy algorithm I get about 36 seconds. I realize that 15 seconds represents a 30% increase, but having typdef'd all variables I expceted to see more than that.
The python+numpy algorithm is as follows:
import numpy as np
def monteCarlo(sims, pers): """ static python implementation of monte carlo simulation" """ g2 = np.array([0.01, -0.03]) g3 = np.array([0.02, 0.01, -0.03]) marcov2 = np.array([[0.9, 0.1], [0.5, 0.5]]).cumsum(1)
for t in range(1, pers): rand_num = np.random.rand() y2[sim, t] = g2[s2] + y2[sim, t - 1] + epsilon[t] y3[sim, t] = g3[s3] + y3[sim, t - 1] + epsilon[t] s2 = <unsigned int> np.where(marco2[<unsigned int> s2, :] > rand_num)[0][0] s3 = <unsigned int> np.where(marco3[<unsigned int> s3, :] > rand_num)[0][0]
return [y2, y3]
I am new to cython and recognize some of the cython code may be un-needed (perhaps the casing of s2 and s3 towards the bottom), but I tried to follow the cython and numpy tutorial in the cython docs.
Any suggestions on how to get more of a speed up??
Hi Spencer,
The largest speedups in cython over well-written python code come from
removing pure python function calls from within loops. `np.where` and
array slicing (e.g. `marco2[s2, :]`) are both pure python calls, and in
your code appear within a nested loop. This is why the code is slower than
you'd expect.
Since you only require the first result from each "where" operation, I'd
suggest replacing them with a short cythonized loop to find the value you
need.
Hope that helps!
Jake
On Mon, Oct 8, 2012 at 5:03 PM, Spencer Lyon <spencerly...@gmail.com> wrote:
> I have written an algorithm to do any number monte carlo simulations for a
> given system.
> When I do 10,000 simulations each of length 254, my python+numpy routine
> takes about 51 seconds to run.
> When I test the same algorithm under my cython+numpy algorithm I get about
> 36 seconds. I realize that 15 seconds represents a 30% increase, but having
> typdef'd all variables I expceted to see more than that.
> I am new to cython and recognize some of the cython code may be un-needed
> (perhaps the casing of s2 and s3 towards the bottom), but I tried to follow
> the cython and numpy tutorial in the cython docs.
> Any suggestions on how to get more of a speed up??
I also wanted to add that one such place that you'll want to replace a call to a numpy function is your call to np.random.rand. I've found that drawing random numbers directly from randomkit (which is what numpy.random calls under the hood), rather than going through the numpy interface can give some large performance increases. As an example, take a look at cIntegratorSimple.pyx in: https://bitbucket.org/joshua.adelman/pylangevin-integrator/src
This has given me a 4x speed-up in some cases.
Hope that helps, Josh
On Tuesday, October 9, 2012 2:11:42 AM UTC-4, Jake wrote:
> The largest speedups in cython over well-written python code come from > removing pure python function calls from within loops. `np.where` and > array slicing (e.g. `marco2[s2, :]`) are both pure python calls, and in > your code appear within a nested loop. This is why the code is slower than > you'd expect.
> Since you only require the first result from each "where" operation, I'd > suggest replacing them with a short cythonized loop to find the value you > need. > Hope that helps! > Jake
> On Mon, Oct 8, 2012 at 5:03 PM, Spencer Lyon <spence...@gmail.com<javascript:> > > wrote:
>> I have written an algorithm to do any number monte carlo simulations for >> a given system.
>> When I do 10,000 simulations each of length 254, my python+numpy routine >> takes about 51 seconds to run.
>> When I test the same algorithm under my cython+numpy algorithm I get >> about 36 seconds. I realize that 15 seconds represents a 30% increase, but >> having typdef'd all variables I expceted to see more than that.
>> I am new to cython and recognize some of the cython code may be un-needed >> (perhaps the casing of s2 and s3 towards the bottom), but I tried to follow >> the cython and numpy tutorial in the cython docs.
>> Any suggestions on how to get more of a speed up??