Faster Random Numbers with PHP

Random numbers functions rand() and mt_rand are easy to use and pretty fast. Numbers produced by these functions range from 0 to PHP_INT_MAX unless you specify your own range. In case you use a custom range, it generates a random number within that range, but – it gets slower.

rand( $min , $max );    //slower

I have bench-marked the time taken by ten thousand calls to rand() with and without specifying a range. The results show that rand($min,$max) takes about 58% extra time compared to rand().

//10,000 iterations of
 
rand( );                    //Time taken: 0.0028 Seconds
rand( $min , $max );        //Time taken: 0.0062 Seconds

Without any range specified, rand went significantly faster. Here are ways to achieve better, although not equal, speed of random number generation if the minimum end of your range is 0 and the maximum value is anything less than or equal to PHP_INT_MAX.

$max    = 500;                          //Inclusive
$number = mt_rand( ) % ( $max + 1 );    //Time taken: 0.0038 Sec (10,000 iterations)
echo $number;                           //$number is now a random integer between 0 and 500.

Alternatively, if your desired range has minimum value 0 and the maximum value lesser than PHP_INT_MAX, and your maximum value can be expressed as 2^n - 1 where n is a whole number representing the number of bits the resulting integer would take, an even better alternative is:

//2^0 -1 = 0     00000000
//2^1 -1 = 1     00000001
//2^2 -1 = 3     00000011
//2^3 -1 = 7     00000111
//2^4 -1 = 15    00001111
//2^5 -1 = 31    00011111
//2^6 -1 = 63    00111111
//.
//.
//.
//2^31 -1 = 2147483647
//2^32 -1 = -1   Unfortunately you Cannot use it - see notes.
 
$max = 255;      //Inclusive
$rand = mt_rand( ) & $max;

So, why -1 does not work as $max in this solution?

The answer is that -1 (despite being a 2^n - 1 integer) cannot be used as $max in our second alternative solution because rand() generates random positive integers that are always 31 bits (on 32bit platforms) or 63 bits (on 64bit platforms). So, & will never let the resultant random integer have its most significant bit (or sign bit) ON and the random number will always remain positive as with 2^31 - 1.

To bypass the limit of PHP_INT_MAX or to generate larger random numbers that fit UNSIGNED INT and BIGINT MySQL data types, read my post that explains how to generate large random numbers.

This was the toughest way to work with random numbers in languages like php 🙂 but it is always good to learn.