PHP列表+爆炸VS substr + strpos - 什么更有效?

Kat*_*a S 8 php string extract

示范文本:

$text = 'Administration\Controller\UserController::Save';
Run Code Online (Sandbox Code Playgroud)

任务 - 提取所有内容::

选项1:

list($module) = explode('::',$text);
Run Code Online (Sandbox Code Playgroud)

选项2:

$module = substr($text, 0, strpos($text, '::');
Run Code Online (Sandbox Code Playgroud)

哪个选项更有效?

lu *_*cip 13

我跑了一个测试,似乎第一个解决方案更快.以下是测试它的代码:

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

function solution1($text)
{
    for($i = 0; $i < 10000; $i++)
        list($module) = explode('::',$text);
}

function solution2($text)
{
    for($i = 0; $i < 10000; $i++)
        $module = substr($text, 0, strpos($text, '::'));
}

$text = 'Administration\Controller\UserController::Save';

$time_start = microtime_float();

solution1($text);

$time_end = microtime_float();
$time = $time_end - $time_start;

echo "Did solution1 in $time seconds.\n";

$time_start = microtime_float();

solution2($text);

$time_end = microtime_float();
$time = $time_end - $time_start;

echo "Did solution2 in $time seconds.\n";
Run Code Online (Sandbox Code Playgroud)

测试1:溶液1在0.19701099395752秒内.解决方案2在0.38502216339111秒.

测试2:溶液1在0.1990110874176秒内.解决方案2在0.37402105331421秒.

测试3:溶液1在0.19801092147827秒内.解决方案2在0.37002205848694秒.


sra*_*ain 7

substr+strpos 将更快,减少CPU时间,减少使用memeroy.

让我们从php soruce代码中找到答案.

explode 第一:

PHP_FUNCTION(explode) 
{ 
    // other codes

    array_init(return_value); 

    if (str_len == 0) { 
        if (limit >= 0) { 
            add_next_index_stringl(return_value, "", sizeof("") - 1, 1); 
        } 
        return; 
    } 


    // other code
    if (limit > 1) { 
        php_explode(&zdelim, &zstr, return_value, limit); 
    } else if (limit < 0) { 
        php_explode_negative_limit(&zdelim, &zstr, return_value, limit); 
    } else { 
        add_index_stringl(return_value, 0, str, str_len, 1); 
    } 
}


PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit)
{
    char *p1, *p2, *endp;

    endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);

    p1 = Z_STRVAL_P(str);
    p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);

    if (p2 == NULL) {
        add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);
    } else {
        do { 
            add_next_index_stringl(return_value, p1, p2 - p1, 1);
            p1 = p2 + Z_STRLEN_P(delim);
        } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
                 --limit > 1);

        if (p1 <= endp)
            add_next_index_stringl(return_value, p1, endp-p1, 1);
    }    
}
Run Code Online (Sandbox Code Playgroud)

explodephp_memnstr多次和add_next_index_stringl多次呼叫将进行操作the result list.

现在strpos:

PHP_FUNCTION(strpos)
{
    zval *needle;
    char *haystack;
    char *found = NULL;
    char  needle_char[2];
    long  offset = 0;
    int   haystack_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) {
        return;
    }

    if (offset < 0 || offset > haystack_len) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string");
        RETURN_FALSE;
    }

    if (Z_TYPE_P(needle) == IS_STRING) {
        if (!Z_STRLEN_P(needle)) {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");
            RETURN_FALSE;
        }

        found = php_memnstr(haystack + offset,
                            Z_STRVAL_P(needle),
                            Z_STRLEN_P(needle),
                            haystack + haystack_len);
    } else {
        if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {
            RETURN_FALSE;
        }
        needle_char[1] = 0;

        found = php_memnstr(haystack + offset,
                            needle_char,
                            1,
                            haystack + haystack_len);
    }

    if (found) {
        RETURN_LONG(found - haystack);
    } else {
        RETURN_FALSE;
    }
}

PHP_FUNCTION(substr)
{
    // other code about postion
    RETURN_STRINGL(str + f, l, 1);
}
Run Code Online (Sandbox Code Playgroud)

它只调用php_memnstr一次,并substr在memery中操作输入字符串,返回sub.


Ale*_*ruk 6

在我的系统上:

~/pb$ uname -a && php -v
Linux hostname 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1+deb7u1 x86_64 GNU/Linux
PHP 5.4.19-1~dotdeb.1 (cli) (built: Aug 27 2013 00:42:43) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
    with XCache v3.0.3, Copyright (c) 2005-2013, by mOo
    with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
    with XCache Cacher v3.0.3, Copyright (c) 2005-2013, by mOo
Run Code Online (Sandbox Code Playgroud)

我有结果:

~/pb$ ./test ListVsSubstr
[============================================================>] 1000 u | 8134 u/s | Est: 0.0 s | Mem: 335.74 KB | Max: 357.96 KB
[============================================================>] 1000 u | 7808 u/s | Est: 0.0 s | Mem: 336.14 KB | Max: 357.96 KB
Test name       Repeats         Result          Performance 
list+explode    1000            0.044890 sec    +0.00%
substr+strpos   1000            0.052825 sec    -17.68%
Run Code Online (Sandbox Code Playgroud)

测试代码在这里:链接.不时的结果略有不同,但list+explode总是快15%以上.

不同的系统和PHP版本可能会有不同的结果.您必须自己检查,并确保环境配置与您的生产相同.