简体   繁体   中英

PHP string versus boolean speed test

I'm looking at trying to optimise a particular function in a PHP application and foolishly assumed that a boolean lookup in an 'if' statement would be quicker than a string compare. But to check it I put together a short test (see below) using microtime . To my surprise, the string lookup was quicker.

Is there anything wrong with my test (I'm wired on too much coffee, so I'm suspicious of my own code)? If not, I would be interested in any comments people have around string versus boolean lookups in PHP.

The result for the first test (boolean lookup) was 0.168 seconds.

The result for the second test (string lookup) was 0.005 seconds.

<?php
    $how_many = 1000000;
    $counter1 = 0;
    $counter2 = 0;

    $abc = array('boolean_lookup'=>TRUE, 'string_lookup'=>'something_else');

    $start = microtime();
    for ($i = 0; $i < $how_many; $i++)
    {
        if ($abc['boolean_lookup'])
        {
            $counter1++;
        }
    }

    echo ($start - microtime());

    echo '<hr>';

    $start = microtime();
    for ($i = 0; $i < $how_many; $i++)
    {
        if ($abc['string_lookup'] == 'something_else')
        {
            $counter2++;
        }
    }

    echo ($start - microtime());

Yes, you've had too much coffee. You need to use microtime(true) otherwise your date calculations are working on the milliseconds but completely ignoring seconds. Also, use current time - start time to measure duration, not start time - current time , or else you get a negative time. Try the following code instead:

<?php

$how_many = 5000000;
$counter1 = 0;
$counter2 = 0;

$abc = array('boolean_lookup'=>TRUE, 'string_lookup'=>'something_else');

$start = microtime(true);
for($i = 0; $i < $how_many; $i++)
{
    if($abc['boolean_lookup'])
    {
        $counter1++;
    }

}

echo "FIRST: ", (microtime(true) - $start), "\n";

$start = microtime(true);
for($i = 0; $i < $how_many; $i++)
{
    if($abc['string_lookup'] == 'something_else')
    {
        $counter2++;
    }

}

echo "SECOND: ", (microtime(true) - $start), "\n";

Doing a general if ($var) is not a bool comparison (in a way that's similar to a "string comparison"). You might want to adjust the bool comparison a bit.

Try the test again with if ($abc['boolean_lookup'] == TRUE) or if ($abc['boolean_lookup'] === TRUE) (2 vs. 3 equals signs).

I made a test including the bool comparison, and the three-equals signs comparisons as well. And additionally a loop to do it 3 times, as the results may vary on a number of external factors.

Since the total time of script excution is fairly long this way I've lowereed the $how_many = 5000000; to $how_many = 3000000;

Here is the final script:

<?php
function DoTest(){

    $how_many = 3000000;
    $counter1 = 0;
    $counter2 = 0;
    $counter3 = 0;
    $counter4 = 0;
    $counter5 = 0;
    $counter6 = 0;

    $abc = array('boolean_lookup'=>TRUE, 'string_lookup'=>'something_else');

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['boolean_lookup']){
            $counter1++;
        }

    }
    echo "GENERAL-IF ON A BOOL: ", (microtime(true) - $start)*10, "<br />\n";

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['string_lookup']){
            $counter2++;
        }

    }
    echo "GENERAL-IF ON A STRING: ", (microtime(true) - $start)*10, "<br />\n";

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['boolean_lookup'] == TRUE){
            $counter3++;
        }

    }
    echo "TWO-EQUALL-IF ON A BOOL : ", (microtime(true) - $start)*10, "<br />\n";

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['string_lookup'] == 'something_else'){
            $counter4++;
        }

    }
    echo "TWO-EQUALL-IF ON A STRING : ", (microtime(true) - $start)*10, "<br />\n";

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['boolean_lookup'] === TRUE){
            $counter5++;
        }

    }
    echo "THREE-EQUALL-IF ON A BOOL : ", (microtime(true) - $start)*10, "<br />\n";

    $start = microtime(true);
    for($i = 0; $i < $how_many; $i++){
        if($abc['string_lookup'] === 'something_else'){
            $counter6++;
        }

    }
    echo "THREE-EQUALL-IF ON A STRING : ", (microtime(true) - $start)*10, "<br />\n";

}

$number_of_tests = 3;
for($i = 0; $i < $number_of_tests; $i++){
    echo "<br />\n<br />\n== Test #".($i+1)."<br />\n";
    DoTest();
}
?>

And the results:

== Test #1
GENERAL-IF ON A BOOL: 7.61245965958
GENERAL-IF ON A STRING: 7.49043941498
TWO-EQUALL-IF ON A BOOL : 8.92991065979
TWO-EQUALL-IF ON A STRING : 10.3996396065
THREE-EQUALL-IF ON A BOOL : 8.02039146423
THREE-EQUALL-IF ON A STRING : 9.25590991974


== Test #2
GENERAL-IF ON A BOOL: 7.74684906006
GENERAL-IF ON A STRING: 7.58201122284
TWO-EQUALL-IF ON A BOOL : 8.90240907669
TWO-EQUALL-IF ON A STRING : 10.2967596054
THREE-EQUALL-IF ON A BOOL : 8.08442115784
THREE-EQUALL-IF ON A STRING : 9.2577290535


== Test #3
GENERAL-IF ON A BOOL: 7.63362884521
GENERAL-IF ON A STRING: 7.5103187561
TWO-EQUALL-IF ON A BOOL : 8.92127037048
TWO-EQUALL-IF ON A STRING : 10.4210495949
THREE-EQUALL-IF ON A BOOL : 8.02319049835
THREE-EQUALL-IF ON A STRING : 9.25379991531

So, my conclusion is that when doing a comparison (with equals sign) the bool is the winner, no doubt.

However, when doing a simple plain general if()-statement the string returns earlier then the bool.

Some other day I might check out if there is a difference in returning true or false (ie. does it take longer to detect the opposite ?)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM