首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP strtr与str_replace基准测试

PHP strtr与str_replace基准测试
EN

Stack Overflow用户
提问于 2011-10-01 21:31:42
回答 3查看 4.6K关注 0票数 2

我很好奇做字符串转换最有效的方法是什么。给定n个输入字符串和一组翻译,通常哪种方法是最有效的?我目前使用strtr(),但已经测试了各种循环方法、带数组的str_replace()等。strtr()方法在我的系统上进行了最快的基准测试,这取决于转换,但我很好奇是否有我还没有想到的更快的方法。

如果相关,我的特定用例涉及为终端将2字节字符串转换为ANSI颜色序列。示例:

代码语言:javascript
复制
// In practice, the number of translations is much greater than one...
$out = strtr("|rThis should be red", array('|r' => "\033[31m"));
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-20 20:34:28

对于简单的替换,strtr似乎更快,但当您有许多搜索字符串的复杂替换时,str_replace似乎具有优势。

票数 3
EN

Stack Overflow用户

发布于 2014-05-07 21:45:23

我为这两个功能的个人需求做了一个简单的基准测试。目标是将小写的“e”更改为大写的“E”。

代码语言:javascript
复制
<?php

$stime = time();

for ($i = 0; $i < 1000000; $i++) {
    str_replace('e', 'E', "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.");
}

echo time() - $stime . "\n";

?>

这段使用str_replace的代码在6秒内运行。现在,strtr函数也是如此:

代码语言:javascript
复制
<?php

$stime = time();

for ($i = 0; $i < 1000000; $i++) {
    strtr("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.", 'e', 'E');
}

echo time() - $stime . "\n";

?>

这只花了4秒钟。

因此,正如T0xicCode所说,对于这种特别简单的情况,strtr确实比str_replace更快,但差别并不是很大。

票数 1
EN

Stack Overflow用户

发布于 2016-07-28 00:41:04

使用直接字符替换时,strtr()的性能最好。更长的字符串给了str_replace()更大的优势。

例如,下面的代码在我的(共享虚拟主机)系统上产生了以下结果:

代码语言:javascript
复制
Execution timings on PHP 7.0.6:
test_strtr(): 0.37670969963074; result: Lorem ipsum dolor sit amet\, \tconsectetur adipiscing elit\, \nsed do eiusmod \%tempor \'incididunt\' ut labore et DELIMITER dolore\; trunc8 \\magna \"aliqua\".
test_str_ireplace(): 0.73557734489441; result: Lorem ipsum dolor sit amet, \tconsectetur adipiscing elit, \\nsed do eiusmod \%tempor \'incididunt\' ut labore et de-limiter dolore\; trunc8 \\magna \"aliqua\".
test_str_replace(): 0.28119778633118; result: Lorem ipsum dolor sit amet, \tconsectetur adipiscing elit, \\nsed do eiusmod \%tempor \'incididunt\' ut labore et DELIMITER dolore\; trunc8 \\magna \"aliqua\".

当我们去掉'delimiter‘和'truncate’时,结果变成:

代码语言:javascript
复制
Execution timings on PHP 7.0.6:
test_strtr(): 0.14877104759216; result: Lorem ipsum dolor sit amet\, \tconsectetur adipiscing elit\, \nsed do eiusmod \%tempor \'incididunt\' ut labore et DELIMITER dolore\; truncate \\magna \"aliqua\".
test_str_ireplace(): 0.58186745643616; result: Lorem ipsum dolor sit amet, \tconsectetur adipiscing elit, \\nsed do eiusmod \%tempor \'incididunt\' ut labore et DELIMITER dolore\; truncate \\magna \"aliqua\".
test_str_replace(): 0.20531725883484; result: Lorem ipsum dolor sit amet, \tconsectetur adipiscing elit, \\nsed do eiusmod \%tempor \'incididunt\' ut labore et DELIMITER dolore\; truncate \\magna \"aliqua\".

因此,从PHP 7.0.6开始,strtr()由于替换时间较长而遭受了相当大的损失。代码:

代码语言:javascript
复制
const LOOP = 333;
const SQL_ESCAPE_MAP = array( // see https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#MySQL_Escaping
    "\x00"  =>  '\x00', // NUL
    "\n"        =>  '\n',       // LF
    "\r"        =>  '\r',       // CR
    "\\"        =>  '\\\\', // backslash
    "'"         =>  "\'",       // single quote
    '"'         =>  '\"',       // double quote
    "\x1a"  =>  '\x1a', // SUB or \Z (substitute for an invalid character)
    "\t"        =>  '\t',   // TAB
    "\x08"  =>  '\b',   // BS
    '%'         =>  '\%',   // Percent
    '_'         =>  '\_',   // Underscore
    ';'         =>  '\;',   // Semicolon
    ','         =>  '\,',   // Comma
    'delimiter' =>  'de-limiter', // SQL delimiter keyword
    'truncate'  =>  'trunc8', // SQL truncate keyword
);

const SQL_SEARCH = array("\x00", "\n", "\r", "\\", "'", '"', "\x1a", "\t", "\x08", "%", ";", 'delimiter', 'truncate');
const SQL_REPLACE = array('\x00','\n','\r','\\\\',"\'",'\"', '\x1a', '\t', '\b', '\%', '\;', 'de-limiter', 'trunc8');

const TEST_STRING = "Lorem ipsum dolor sit amet, \tconsectetur adipiscing elit, \nsed do eiusmod %tempor 'incididunt' ut labore et DELIMITER dolore; truncate \magna \"aliqua\".";

function test_strtr() {
  for($i= 0; $i < LOOP; $i++) {
    $new_string = strtr(TEST_STRING, SQL_ESCAPE_MAP);
  }
    return $new_string;
}
function test_str_ireplace() {
  for($i= 0; $i < LOOP; $i++) {
    $new_string = str_ireplace(SQL_SEARCH, SQL_REPLACE, TEST_STRING);
  }
    return $new_string;
}
function test_str_replace() {
  for($i= 0; $i < LOOP; $i++) {
    $new_string = str_replace(SQL_SEARCH, SQL_REPLACE, TEST_STRING);
  }
    return $new_string;
}

$timings = array(
    'test_strtr' => 0,
    'test_str_ireplace' => 0,
    'test_str_replace' => 0,
);

for($i= 0; $i < LOOP; $i++) {
    foreach(array_keys($timings) as $func) {
        $start = microtime(true);
        $$func = $func();
        $timings[$func] += microtime(true) - $start;
    }
}

echo '<pre>Execution timings on PHP ' . phpversion('tidy') . ":\n";
foreach(array_keys($timings) as $func) {
    echo $func . '(): ' . $timings[$func] . '; result: ' . $$func . "\n";
}
echo "</pre>\n";

注意:

  1. 此示例代码并不是作为mysqli::real_escape_string的生产替代方案来代替DB连接(二进制/多字节编码的input).
  2. Clearly,存在问题,差别很小)。出于助记的原因(匹配和替换是如何组织的),我更喜欢使用strtr本身获取的关联数组。(这并不是说str_replace的array_keys()不能实现这一点。)这种情况下的差异肯定在微优化的范围内,并且对于不同的输入可以有很大的不同。如果您需要每秒处理数千次大型字符串,请使用您的特定数据进行基准测试。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7620549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档