php preg_replace()与(vs。)ord()

时间:2010-10-22 09:04:21

标签: php function comparison performance

什么是更快,因为camelCase强调; 使用preg_replace()或使用ord()?

我的猜测是使用ord的方法会更快, 因为preg_replace可以做更多的事情。

<?php
function __autoload($class_name){
    $name = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class_name));
    require_once("some_dir/".$name.".php");
}
?>

OR

<?php
function __autoload($class_name){
// lowercase first letter
$class_name[0] = strtolower($class_name[0]);

$len = strlen($class_name);
for ($i = 0; $i < $len; ++$i) {
    // see if we have an uppercase character and replace
    if (ord($class_name[$i]) > ord('A') && ord($class_name[$i]) < ord('Z')) {
        $class_name[$i] = '_' . strtolower($class_name[$i]);
        // increase length of class and position
        ++$len;
        ++$i;
    }
}

return $class_name;
}
?>

免责声明 - 代码示例取自StackOverflowQuestion 1589468

编辑,在jensgram的数组建议后发现array_splice我想出了以下内容:

<?php
function __autoload ($string)// actually, function camel2underscore
{
$string  =  str_split($string);
$pos     =  count( $string );
while ( --$pos > 0 )
{
    $lower  =  strtolower( $string[ $pos ] );
    if ( $string[ $pos ] === $lower )
    {
        // assuming most letters will be underscore this should be improvement
        continue;
    }
    unset( $string[ $pos ] );
    array_splice( $string , $pos , 0 , array( '_' , $lower ) );
}
$string  =  implode( '' , $string );
return $string;
}
// $pos could be avoided by using the array key, something i might look into later on.
?>

当我将测试这些方法时,我将添加这个 但随时随地告诉我你的结果; p

5 个答案:

答案 0 :(得分:2)

我认为(而且我非常肯定)preg_replace方法会更快 - 但是如果你想知道,为什么不做一个基准调用这两个函数100000次并测量时间?

答案 1 :(得分:1)

(不是答案,但是太长时间无法发表评论 - 将会CW)

如果你要比较,你至少应该优化ord()版本。

$len = strlen($class_name);
$ordCurr = null;
$ordA = ord('A');
$ordZ = ord('Z');
for ($i = 0; $i < $len; ++$i) {
    $ordCurr = ord($class_name[$i]);
    // see if we have an uppercase character and replace
    if ($ordCurr >= $ordA && $ordCurr <= $ordZ) {
        $class_name[$i] = '_' . strtolower($class_name[$i]);
        // increase length of class and position
        ++$len;
        ++$i;
    }
}

此外,将名称推送到堆栈(数组)并在末尾连接可能比字符串连接更有效。

但是这首先值得优化/分析吗?

答案 2 :(得分:1)

我的用例与OP略有不同,但我认为它仍然说明了preg_replace和手动字符串操作之间的区别。

$a = "16 East, 95 Street";

echo "preg: ".test_preg_replace($a)."\n";
echo "ord:  ".test_ord($a)."\n";

$t = microtime(true);
for ($i = 0; $i &lt 100000; $i++) test_preg_replace($a);
echo (microtime(true) - $t)."\n";
$t = microtime(true);
for ($i = 0; $i &lt 100000; $i++) test_ord($a);
echo (microtime(true) - $t)."\n";

function test_preg_replace($s) {
    return preg_replace('/[^a-z0-9_-]/', '-', strtolower($s));
}
function test_ord($s) {
    $a = ord('a');
    $z = ord('z');
    $aa = ord('A');
    $zz = ord('Z');
    $zero = ord('0');
    $nine = ord('9');
    $us = ord('_');
    $ds = ord('-');
    $toret = ''; 
    for ($i = 0, $len = strlen($s); $i < $len; $i++) {
        $c = ord($s[$i]);
        if (($c >= $a && $c &lt;= $z) 
            || ($c >= $zero && $c &lt;= $nine)
            || $c == $us 
            || $c == $ds)
        {   
            $toret .= $s[$i];
        }   
        elseif ($c >= $aa && $c &lt;= $zz)
        {   
            $toret .= chr($c + $a - $aa); // strtolower
        }   
        else
        {   
            $toret .= '-';
        }   
    }   
    return $toret;
}

结果

0.42064881324768
2.4904868602753

所以preg_replace方法非常优越。此外,字符串连接比插入数组和插入数组要快一些。

答案 3 :(得分:0)

如果您只想将驼峰大小写转换为下划线,那么您可以编写一个比ord或preg_replace更有效的函数,其时间比分析它们的时间短。

答案 4 :(得分:0)

我使用以下四个函数编写了一个基准测试,我发现在Magento中实现的是最快的一个(它是Test4):

测试1:

/**
 * @see: http://www.paulferrett.com/2009/php-camel-case-functions/
 */
function fromCamelCase_1($str)
{
    $str[0] = strtolower($str[0]);
    return preg_replace('/([A-Z])/e', "'_' . strtolower('\\1')", $str);
}

的Test2:

/**
 * @see: http://stackoverflow.com/questions/3995338/phps-preg-replace-versusvs-ord#answer-3995435
 */
function fromCamelCase_2($str)
{
    // lowercase first letter
    $str[0] = strtolower($str[0]);

    $newFieldName = '';
    $len = strlen($str);
    for ($i = 0; $i < $len; ++$i) {
        $ord = ord($str[$i]);
        // see if we have an uppercase character and replace
        if ($ord > 64 && $ord < 91) {
            $newFieldName .= '_';
        }
        $newFieldName .= strtolower($str[$i]);
    }
    return $newFieldName;
}

Test3的:

/**
 * @see: http://www.paulferrett.com/2009/php-camel-case-functions/#div-comment-133
 */
function fromCamelCase_3($str) {
    $str[0] = strtolower($str[0]);
    $func = create_function('$c', 'return "_" . strtolower($c[1]);');
    return preg_replace_callback('/([A-Z])/', $func, $str);
}

TEST4:

/**
 * @see: http://svn.magentocommerce.com/source/branches/1.6-trunk/lib/Varien/Object.php :: function _underscore($name)
 */
function fromCamelCase_4($name) {
    return strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $name));
}

结果使用字符串“getExternalPrefix”1000次:

fromCamelCase_1: 0.48158717155457
fromCamelCase_2: 2.3211658000946
fromCamelCase_3: 0.63665509223938
fromCamelCase_4: 0.18188905715942

结果使用“WAytGLPqZltMfHBQXClrjpTYWaEEkyyu”等随机字符串1000次:

fromCamelCase_1: 2.3300149440765
fromCamelCase_2: 4.0111720561981
fromCamelCase_3: 2.2800230979919
fromCamelCase_4: 0.18472790718079

使用测试字符串我得到了不同的输出 - 但这不应该出现在你的系统中:

original:
MmrcgUmNfCCTOMwwgaPuGegEGHPzvUim

last test:
mmrcg_um_nf_cc_to_mwwga_pu_geg_eg_hpzv_uim

other tests:
mmrcg_um_nf_c_c_t_o_mwwga_pu_geg_e_g_h_pzv_uim

正如您在时间戳上看到的那样 - 最后一次测试在两个测试中的时间相同:)