Search code examples
phpphp-7

PHP performance of using constants instead of strings


I am creating a web app in pure PHP and I have to interchange some status between functions, this status can be around 5 like for example: user_created, user_active, user_inactive and so on. So, what't the most efficient way to do this?

Inicially I was returning strings from my functions, but i know that strings comparison can be quite slow and more on if the name of the status get longer and longer, so I thought on creating constants with integer values, but it got me thinking... if the PHP parser still needs to read the whole constant name before comparing, is not it the same than using a string, or a variable? is there a more efficient way to do this?

sorry if it looks like a trivial question, I just try to optimize every aspect of my app

if it's not totally clear what i am going to do is really simple:

function getUserStatus() {
    // return some value
}

and then use it as follows

$userStatus = getUserStatus();
switch ($userStatus) {
    // all possible cases
}

Solution

  • You can test it with something like below.

    Note that PHP Optimizes a lot, and stores compiled byte code in its cache. http://php.net/manual/en/intro.opcache.php

    The results

    string 0.38328790664673 constant 0.50211310386658

    string 0.38391804695129 constant 0.51568698883057

    What surprises me is that String seems to be faster.

    I noted the following setting in the opcache config:

    opcache.interned_strings_buffer integer
    The amount of memory used to store interned strings, in megabytes. 
    This configuration directive is ignored in PHP < 5.3.0.
    

    A pretty neat setting with like 0 documentation. PHP uses a technique called string interning to improve performance so, for example, if you have the string "foobar" 1000 times in your code, internally PHP will store 1 immutable variable for this string and just use a pointer to it for the other 999 times you use it. Cool. This setting takes it to the next level. instead of having a pool of these immutable string for each SINGLE php-fpm process, this setting shares it across ALL of your php-fpm processes. It saves memory and improves performance, especially in big applications.

    So stating that string comparison is slower than constant comparison is a wrong assumption in PHP.

    BUT: You can break this optimalization example:

    $state = "State";
    switch($string) {
        case "Offline" . $state:
        break;
    }
    

    The result of this will be: string 0.61401081085205 constant 0.51961803436279

    In this case the constant comparison will be faster.

    The performance improvements where added to PHP5.4 and here is the RFC https://wiki.php.net/rfc/performanceimprovements

    But note that constants generally make for better refactor able code and therefor better maintainable. Furthermore the performance hit is negligible

    function doSomethingString() {
        return "OfflineState";
    }
    
    const OFFLINE_STATE = 1;
    function doSomethingConstant() {
        return OFFLINE_STATE;
    }
    
    function dummy() {}
    
    // String
    echo('string' . PHP_EOL);
    $start = microtime(true);
    for($i = 0; $i < 10000000; $i++) {
        switch(doSomethingString()) {
            case "OfflineState":
                dummy();
                break;
        }
    }
    echo(PHP_EOL);
    $end = microtime(true);
    echo($end - $start);
    echo(PHP_EOL);
    
    
    //Constant
    echo('constant' . PHP_EOL);
    $start = microtime(true);
    for($i = 0; $i < 10000000; $i++) {
        switch(doSomethingConstant()) {
            case OFFLINE_STATE:
                dummy();
                break;
        }
    }
    echo(PHP_EOL);
    $end = microtime(true);
    echo($end - $start);
    echo(PHP_EOL);
    

    My php version:

    PHP 7.2.8-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Jul 25 2018 10:52:19) ( NTS )
    Copyright (c) 1997-2018 The PHP Group
    Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
        with Zend OPcache v7.2.8-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies