Choose an array element randomly

0

I have an array with the elements:

$base = array(
            'root',
            'user',
            'admin',
            'hack',
            'cloud',
            'apple',
            'linux',
            'blue',
            'dark',
            'pink',
            'free',
            'chard',
            'ligth',
            'moon',
            'teen'
);

I want to select one of the elements at random.

And I have two alternatives. This:

$item = $base[rand(0,count($base)-1)]

And this one:

$item = array_rand(array_flip($base),1);

Is one of the two more efficient than the other? How do they differ?

    
asked by Impulso Like 03.01.2019 в 23:14
source

2 answers

2

I did some tests in the browser with the library pTester :

<?php

require 'pTester/ptester.php';
use ironwoods\tools\ptester\PTester;


function test_one(array $base): void
{
    $x = $base[rand(0, count($base)-1)];
}

function test_two(array $base): void
{
    $x = array_rand(array_flip($base), 1);
}


/**
 * Tests
 *
 */

$base = [
    'root',
    'user',
    'admin',
    'hack',
    'cloud',
    'apple',
    'linux',
    'blue',
    'dark',
    'pink',
    'free',
    'chard',
    'ligth',
    'moon',
    'teen',
];

$arr_with_tests = [
    test_one($base),
    test_two($base),
];

PTester::setNumberOfRunningTests(2000);
PTester::setRunningCycles(TRUE);
PTester::test($arr_with_tests);

If you repeat several times:

Tested method number: 1
Used time: 7.65061378479E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 7.8002333641052E-8 miliseconds
Used memory: 0 bytes.


Tested method number: 1
Used time: 7.4004173278809E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 7.5004696846008E-8 miliseconds
Used memory: 0 bytes.


Tested method number: 1
Used time: 7.7004194259644E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 8.3004355430603E-8 miliseconds
Used memory: 0 bytes.

If I am interpreting the result correctly it seems that the first method is somewhat slower .


Plus: use mt_rand () instead of rand ()

It is recommended to use mt_rand() which is faster than rand() , it also seems that rand() has other problems and is completely replaced in the latest versions of PHP. See this thread about differences .

If we repeat the tests, using mt_rand () instead of rand () we would have:

Tested method number: 1
Used time: 8.1004023551941E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 7.700502872467E-8 miliseconds
Used memory: 0 bytes.


Tested method number: 1
Used time: 6.9506883621216E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 8.0002188682556E-8 miliseconds
Used memory: 0 bytes.


Tested method number: 1
Used time: 7.7004432678223E-8 miliseconds
Used memory: 0 bytes.

Tested method number: 2
Used time: 8.2505106925964E-8 miliseconds
Used memory: 0 bytes.
    
answered by 04.01.2019 в 00:09
0

With the second form you work more to obtain the random value. First you make an array_flip, which forces PHP to work on all the elements of the array, and then you make an array_rand that again makes it work on the entire array.

The first form, however, obtains the random value through the creation of a random index, which is a much "lighter" value to obtain and then only "attacks" directly on this value. (first the array length is evaluated, but this again is something very fast and cheap to do for PHP).

However, talking about the efficiency of these functions only makes sense if you invoke them a high number of times. In any other sense, you will not notice any difference (unless the input array is something very large, in which case the first of the forms will become more patent as the best way).

What you can do to slightly optimize your query is instead of getting the length of the array under each iteration, since it is always the same, it is only doing the evaluation once:

$n = count($base); //hazlo fuera y así cada vez que iteres para obtener un aleatorio, no tienes que invocar la funcion una y otra vez.

$rand = mt_rand(0,$n-1);
$item = $base[$rand];

It's also a good idea to change the rand function by mt_rand

    
answered by 04.01.2019 в 00:27