解析一个简单明确定义的字符串的最有效方法?

时间:2015-10-31 08:11:18

标签: php performance substr

我只是问,因为这循环了数百万次。

字符串就像这样:

01-20

它总是那样... 2位数(前导零)后跟连字符和另外2位数(前导零)。我只需要将第一个(作为整数)分配给一个变量,将第二个(作为整数)分配给另一个变量。

str_split? SUBSTR?爆炸?正则表达式?

2 个答案:

答案 0 :(得分:4)

给定变量$txt,这具有最佳性能:

    $a = (int)$txt;
    $b = (int)substr($txt, -2); 

您可以使用以下脚本衡量不同替代方案的效果:

<?php
$txt = "01-02";
$test_count = 4000000;

// SUBSTR -2
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
    $a = (int)$txt; // numeric conversion ignores second part of string.
    $b = (int)substr($txt, -2); 
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "substr(s,-2): {$a} {$b}, process time: {$duration}ms <br />";

// SUBSTR 3, 2
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
    $a = (int)$txt; // numeric conversion ignores second part of string.
    $b = (int)substr($txt, 3, 2);   
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "substr(s,3,2): {$a} {$b}, process time: {$duration}ms <br />";

// STR_SPLIT
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
    $arr = str_split($txt, 3);
    $a = (int)$arr[0]; // the ending hyphen does not break the numeric conversion
    $b = (int)$arr[1];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "str_split(s,3): {$a} {$b}, process time: {$duration}ms <br />";

// EXPLODE
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
    $arr = explode('-', $txt);
    $a = (int)$arr[0];
    $b = (int)$arr[1];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "explode('-',s): {$a} {$b}, process time: {$duration}ms <br />";

// PREG_MATCH
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
    preg_match('/(..).(..)/', $txt, $arr);
    $a = (int)$arr[1];
    $b = (int)$arr[2];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "preg_match('/(..).(..)/',s): {$a} {$b}, process time: {$duration}ms <br />";
?>

当我在PhpFiddle Lite上运行时,我得到了这样的结果:

substr(s,-2): 1 2, process time: 851ms
substr(s,3,2): 1 2, process time: 971ms
str_split(s,3): 1 2, process time: 1568ms
explode('-',s): 1 2, process time: 1670ms
preg_match('/(..).(..)/',s): 1 2, process time: 3328ms 

如果您只使用一个调用,substr以(s,-2)或(s,3,2)作为参数的性能几乎同样表现良好。有时第二个版本作为赢家出现。 str_splitexplode表现得相当接近,但不是很好,preg_match显然更宽松。结果取决于服务器负载,因此您应该在自己的设置上尝试此操作。但可以肯定的是,正则表达式的负载很重。当你可以使用其他字符串函数完成工作时,请避免使用它们。 当我意识到你可以将原始字符串立即转换为int时,我编辑了我的答案,这将忽略它无法解析的部分。这实际上意味着您可以将第一部分作为数字而不调用任何字符串函数。这使得substr成为绝对的赢家具有决定性作用!

答案 1 :(得分:0)

尝试将字符串转换为数组,然后将每个数组索引用于您想要的不同变量

<?php
$str = '01-20'
$number = explode('-',$str);
$variable_1 = (int)$number[0];
$variable_2 = (int)$number[1];
?>