解析简单明确定义的字符串的最有效方法?
most efficient means of parsing a simple clearly defined string?
我问这个只是因为循环了数百万次。
字符串就是这样:
01-20
总是这样...2 位数字(前导零)后跟连字符和另外 2 位数字(前导零)。我只需要将第一个(作为整数)分配给一个变量,将第二个(作为整数)分配给另一个变量。
str_split?子串?爆炸?正则表达式?
尝试将字符串转换为数组,然后将每个数组索引用于您想要的不同变量
<?php
$str = '01-20'
$number = explode('-',$str);
$variable_1 = (int)$number[0];
$variable_2 = (int)$number[1];
?>
给定一个变量 $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
以 (s, -2) 或 (s, 3, 2) 作为参数的 substr
的性能几乎同样好,前提是您只使用一次调用。有时第二个版本会成为赢家。 str_split
和 explode
表现相当接近,但不是那么好,而 preg_match
显然更松。结果取决于服务器负载,因此您应该在自己的设置上尝试此操作。但可以肯定的是,正则表达式的负载很重。当您可以使用其他字符串函数完成工作时,请避免使用它们。
当我意识到您可以立即将原始字符串转换为 int 时,我编辑了我的答案,这将忽略它无法解析的部分。这实际上意味着您可以在不调用任何字符串函数的情况下将第一部分作为数字获取。这是让 substr
成为绝对赢家的决定性因素!
我问这个只是因为循环了数百万次。
字符串就是这样:
01-20
总是这样...2 位数字(前导零)后跟连字符和另外 2 位数字(前导零)。我只需要将第一个(作为整数)分配给一个变量,将第二个(作为整数)分配给另一个变量。
str_split?子串?爆炸?正则表达式?
尝试将字符串转换为数组,然后将每个数组索引用于您想要的不同变量
<?php
$str = '01-20'
$number = explode('-',$str);
$variable_1 = (int)$number[0];
$variable_2 = (int)$number[1];
?>
给定一个变量 $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
以 (s, -2) 或 (s, 3, 2) 作为参数的 substr
的性能几乎同样好,前提是您只使用一次调用。有时第二个版本会成为赢家。 str_split
和 explode
表现相当接近,但不是那么好,而 preg_match
显然更松。结果取决于服务器负载,因此您应该在自己的设置上尝试此操作。但可以肯定的是,正则表达式的负载很重。当您可以使用其他字符串函数完成工作时,请避免使用它们。
当我意识到您可以立即将原始字符串转换为 int 时,我编辑了我的答案,这将忽略它无法解析的部分。这实际上意味着您可以在不调用任何字符串函数的情况下将第一部分作为数字获取。这是让 substr
成为绝对赢家的决定性因素!