Why is strtolower a bit slower than strtoupper?

I did an experiment out of curiosity. I wanted to see if there is any difference between strtolower()and strtoupper(). I expected it to strtolower()be faster on lowercase lines and vice versa. I found that I strtolower()was slower in all cases (although it is completely negligible until you do it millions of times). That was my test.

$string = 'hello world';
$start_time = microtime();
for ($i = 0; $i < 10000000; $i++) {
    strtolower($string);
}
$timed = microtime() - $start_time;
echo 'strtolower ' . $string . ' - ' . $timed . '<br>';

Repeats for strtolower()and strtoupper()using hello world, hello worldand hello world. Here is the full text. I ran the code several times and got roughly the same results. Here is one test run below.

strtolower hello world - 0.043829
strtoupper hello world - 0.04062
strtolower HELLO WORLD - 0.042691
strtoupper HELLO WORLD - 0.015475
strtolower Hello World - 0.033626
strtoupper Hello World - 0.017022

I believe that the C code in php-src github that controls this is here for strtolower () and here for strtoupper ()

, strtolower(). , .

strtolower() , strtoupper()?

+6
2

, , .

babelstone.co.uk:

, j (ǰ) (U + 01F0 LATIN SMALL LETTER J WITH CARON), (J̌) Unicode (U + 004A LATIN CAPITAL LETTER J + U + 030C ).

.

, strtolower , , , strtolower (, "Ê" ), . UTF-8, , mb_strtolower.

, uppercase , lowercase, , .

, strtolower , , uppercase.

+4

:

PHPAPI char *php_strtoupper(char *s, size_t len)
{
    unsigned char *c, *e;

    c = (unsigned char *)s;
    e = (unsigned char *)c+len;    <-- strtolower uses e = c+len;

    while (c < e) {
        *c = toupper(*c);
        c++;
    }
    return s;
}

PHPAPI zend_string *php_string_toupper(zend_string *s)
{
    unsigned char *c, *e;

    c = (unsigned char *)ZSTR_VAL(s);
    e = c + ZSTR_LEN(s);

    while (c < e) {
        if (islower(*c)) {
            register unsigned char *r;
            zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);

            if (c != (unsigned char*)ZSTR_VAL(s)) {
                memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s));
            }
            r = c + (ZSTR_VAL(res) - ZSTR_VAL(s));
            while (c < e) {
                *r = toupper(*c);
                r++;
                c++;
            }
            *r = '\0';
            return res;
        }
        c++;
    }
    return zend_string_copy(s);
}

PHP_FUNCTION(strtoupper)
{
    zend_string *arg;      <-- strtolower uses zend_string *str;

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_STR(arg)          <-- strtolower uses Z_PARAM_STR(str)
    ZEND_PARSE_PARAMETERS_END();

    RETURN_STR(php_string_toupper(arg));     <-- strtolower uses RETURN_STR(php_string_tolower(str));
}

strtolower

PHPAPI char *php_strtolower(char *s, size_t len)
{
    unsigned char *c, *e;

    c = (unsigned char *)s;
    e = c+len;                  <-- strtoupper uses e = (unsigned char *)c+len;

    while (c < e) {
        *c = tolower(*c);
        c++;
    }
    return s;
}

PHPAPI zend_string *php_string_tolower(zend_string *s)
{
    unsigned char *c, *e;

    c = (unsigned char *)ZSTR_VAL(s);
    e = c + ZSTR_LEN(s);

    while (c < e) {
        if (isupper(*c)) {
            register unsigned char *r;
            zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);

            if (c != (unsigned char*)ZSTR_VAL(s)) {
                memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s));
            }
            r = c + (ZSTR_VAL(res) - ZSTR_VAL(s));
            while (c < e) {
                *r = tolower(*c);
                r++;
                c++;
            }
            *r = '\0';
            return res;
        }
        c++;
    }
    return zend_string_copy(s);
}

PHP_FUNCTION(strtolower)
{
    zend_string *str;     <-- strtoupper uses zend_string *arg; 

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_STR(str)        <-- strtoupper uses Z_PARAM_STR(arg)
    ZEND_PARSE_PARAMETERS_END();

    RETURN_STR(php_string_tolower(str));    <-- strtoupper uses RETURN_STR(php_string_tolower(arg));
}

, .... ,

+4

All Articles