8
$\begingroup$

I want to make my python program fast by using cython, but my inner loop is still making slow python calls to the random number generator! Several years ago this same issue was raised by someone on sage-support and there seemed to be no good solution at that time. It is not convenient for me to pre-generate a long list of random samples because I am actually sampling from various distributions in a way that is conditional on previous samples.

Here's a blog post explaining how this was kludged by connecting from cython to gsl:
http://pyinsci.blogspot.com/2010/12/efficient-mcmc-in-python-errata-and.html

And a stackoverflow post by someone trying to implement the gsl kludge:
https://stackoverflow.com/questions/8177446/random-number-generators-to-work-on-x86-64

$\endgroup$
2
  • $\begingroup$ I don't understand your question. Cython + GSL RNG is exactly how I would implement this. What would you like to differently? $\endgroup$ Commented Sep 4, 2012 at 15:53
  • $\begingroup$ @Aron: Maybe that is the answer to my question -- that Cython + GSL RNG is still the best way to do it. What would I like to do differently? I would like to avoid the extra gsl dependency and avoid the boilerplate involved in linking to it, but I understand that the technology for this may not yet exist. But I am optimistic that we are working towards it, for example with projects like github.com/twiecki/CythonGSL . $\endgroup$
    – none
    Commented Sep 4, 2012 at 16:30

3 Answers 3

7
$\begingroup$

Cython makes code faster by removing the type ambiguity. Since random.py is a pure python module, you can just copy it and add the types to the functions you need. Then cython can optimize the dynamic overhead away.

$\endgroup$
1
  • $\begingroup$ I am actually using numpy.random but this is an interesting suggestion to copy and cythonize the code in the packages that I am using. $\endgroup$
    – none
    Commented Sep 6, 2012 at 18:30
5
$\begingroup$

Following aterrel's suggestion, you could use pyximport to automatically compile the random module:

import pyximport
pyximport.install(pyimport=True)

import random

However, this still will not make it as fast as it would be if you declared static types for the variables in Cython.

$\endgroup$
1
  • 1
    $\begingroup$ Welcome to the site, Jim! Thanks for the nice out-of-the-starting-gate input :) $\endgroup$ Commented Nov 29, 2012 at 10:26
3
$\begingroup$

I'm not sure if these were added recently but it seems like there are now easy ways to generate random numbers quickly without too much overhead. From this article about Monte Carlo simulations in cython we can do

from libc.stdlib cimport rand, RAND_MAX
r = 1 + int(rand()/(RAND_MAX*6.0)) # random integer 1,...,6

As far as I understand you don't need to do anything special when compiling.

For reproducibility during testing you can set a seed

# srand48(time(0)) # Do it this way in production
srand48(100) # For reproducibility in testing
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.