PHP: rand() vs. mt_rand() – what is more accurate, what is faster?

After I was pointed out, that it would be better to use the PHP function mt_rand() instead of rand() for generating random numbers (because mt_rand() should be more accurate), I decided to investigate on that statement. But at first, where is the difference between rand() and mt_rand()?

By use of mt_rand() you can generate random numbers just like with the rand() function. The function call also looks equal on both functions. Though the PHP documentation says mt_rand() is up to 4-times faster and would be create more random/arbitrary numbers. By implication this would mean, that the rand() function creates inaccurate random numbers.

I was not aware of this problem, but after some googleing I discovered that there are a lot of people who think that mt_rand() is the better function. However I had to notice that most of the contributions which complain that rand() is not clean are a “little older”.

Often cited in support of the arguments is an article of Dog.net Development, which visualizes the alleged disadvantages of rand() in contrary to mt_rand(). The already mentioned assertion, rand() would not create random numbers correctly, is claimed by the Dog.net Development author by a short but effective PHP script. Because I wanted to comprehend the asserted problem, I’ve written a similar script.

<?php
header("Content-type: image/png");
$img = imagecreatetruecolor(256, 256)
    or die("Error while creating the graphic.");
$white = imagecolorallocate($img, 255, 255, 255);

for ($x=0; $x<256; $x++)
{
    for ($y=0; $y<256; $y++)
    {
        if (mt_rand(0,1) === 1)
        {
             imagesetpixel($img, $x, $y, $white);
         }
     }
 }
 imagepng($img);
 imagedestroy($img);
?>

The script creates a 256×256 pixel image. Wherein for each pixel, a random number between 0 and 1 is generated. If the number is a 1 the pixel is colored white else the pixel is colored black.
Dog.net ran this algorithm once with mt_rand () and once with the rand () and received the following two graphics (click to enlarge):

mt_rand() vs. rand()

Here it can be seen why many are denouncing the rand() function. On the image that was created using the rand() function a pattern is clearly discernible. This would mean that the random numbers from rand () are not truly random. But…

…at this point I would like to confront my observations. I said earlier on, that the most accusatory articles are a bit dated. So there was enough time to improve the rand() function. Therefore I thought it would be a good idea to recreate the script of Dog.net and see what happens. And lo and behold …

rand

(Picture created using rand())

(Picture created using mt_rand())

…miraculously both functions appear to work very well. All that remains is to verify whether mt_rand () is at least faster than rand(), as it was claimed. For this I have written another small script.

<?php
$start = microtime(true);
for ($i=0; $i<1000000; $i++)
{
     $random = mt_rand(0,1);
}
$end = microtime(true);

$runtimeMtRand= $end - $start;

$start = microtime(true);
for ($i=0; $i<1000000; $i++)
{
     $random = rand(0,1);
}
$end = microtime(true);

$runtimeRand = $end - $start;

echo "Runtime mt_rand(): ".$runtimeMtRand." seconds!";
echo "Runtime rand(): ".$runtimeRand." seconds!";
?>

And at this point, then also follows the second surprise. The script returned the following result:

Runtime mt_rand(): 1.033802986145 seconds!
Runtime rand(): 1.1012179851532 seconds!

mt_rand() is not 4-times fast as rand(). It is not even 2-times as fast. So in my eyes there is no reason to switch from the rand() function to the mt_rand() function.

What do you think? Could I convince you?

Best regards,
Raffi

4 Comments

  1. Micksays:

    Just asking but could it be that in the first test of the rand(); function the fact the image was 256×256 had some impact… multiples of 2 are after all relevant in terms of processing and whatnot and are reflected in architecture… were the image 234×271 or better yet two primes then it might have been a different kettle of fish….. point accepted though it wasn’t pseudo random… which is clearly poor testing from the get go…who let this slip in?

  2. petersays:

    i look for fast rand, i find code: num256 = mt_rand() & 255
    rand() is not good, after ~32.000 iterations repeat numbers (php 5.5.12).

  3. Hello Raffi, I’m not sure what do you mean by a “better” random function. Both are unsafe http://phpsecurity.readthedocs.org/en/latest/Insufficient-Entropy-For-Random-Values.html.

Leave a comment

Please be polite. We appreciate that. Your email address will not be published and required fields are marked