关于表现,做:
之间有什么区别吗?$message = "The request $request has $n errors";
和
$message = sprintf('The request %s has %d errors', $request, $n);
PHP中的?
我会说调用函数涉及更多东西,但我不知道PHP在幕后做什么来扩展变量名。
谢谢!
答案 0 :(得分:30)
没关系。
任何性能提升都是如此微不足道,以至于你会看到它(作为几秒钟内的改进)只有10000s或100000次迭代 - 如果是这样的话。
有关具体数字,请参阅this benchmark。您可以看到它必须使用100,000个函数调用生成1MB +的数据,以在数百毫秒内实现可测量的差异。几乎没有现实生活中的情况。即使是最慢的方法(带有位置参数的“sprintf()”)也只需要0.00456毫秒,最快的是0.00282毫秒。对于任何需要100,000个字符串输出调用的操作,您将有其他因素(例如网络流量),这些因素将比您通过优化它可以节省的100毫秒慢一些。
使用任何使您和其他人的代码最易读和可维护的内容。就我个人而言,sprintf()
方法是一个很好的想法 - 我必须考虑自己开始使用它。
答案 1 :(得分:25)
在所有情况下,第二个都不会更快,因为您提供的是双引号字符串,也必须为变量进行解析。如果您要进行微优化,正确的方法是:
$message = sprintf('The request %s has %d errors', $request, $n);
尽管如此,我认为秒数较慢(因为@Pekka指出差异实际上并不重要),因为函数调用的开销,解析字符串,转换值等等。但请注意,2行代码不等价,因为在第二种情况下,$ n被转换为整数。如果$ n是“无错误”,那么第一行将输出:
The request $request has no error errors
第二个将输出:
The request $request has 0 errors
答案 2 :(得分:20)
对“变量扩展与sprintf”进行了性能分析here。
正如@pekka所说,“使您和其他人的代码最具可读性和可维护性”。当性能增益“低”(〜不到两次)时,忽略它。
总结基准:PHP针对Double-quoted和Heredoc分辨率进行了优化。仅使用
计算非常长的字符串的平均时间百分比请注意,只有sprintf执行一些格式化任务(参见基准测试'%s%s%d%s%f%s'),并且正如@Darhazer所示,它在输出方面有所不同。一个更好的测试是两个基准测试,一个只比较连接时间('%s'格式化程序),其他包括格式化过程 - 例如'%3d%2.2f'和功能等价物,然后将变量扩展为双引号...还有一个使用短模板字符串的基准组合。
基准测试显示sprintf
的主要优点是非常低成本的格式化程序(!)。对于通用模板,我建议使用vsprintf函数。
doubled-quoted (和heredoc)的主要优点是一些性能;当与sprintf的位置标记进行比较时,名义占位符的一些可读性和可维护性随着参数的数量(1之后)而增长。
索引占位符的使用处于sprintf可维护性的一半。
注意:仅在必要时才使用单引号连接。请记住,PHP支持安全语法,如"Hello {$user}_my_brother!"
和"Hello {$this->name}!"
等参考。
答案 3 :(得分:2)
对于将多个String变量注入String,第一个变速器会更快。
$message = "The request $request has $n errors";
对于单次注射,点(。)连接将更快。
$message = 'The request '.$request.' has 0 errors';
使用十亿次循环进行迭代并找到差异。
例如:
<?php
$request = "XYZ";
$n = "0";
$mtime = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$message = "The request {$request} has {$n} errors";
}
$ctime = microtime(true);
echo ($ctime-$mtime);
?>
答案 4 :(得分:1)
我很惊讶,但是对于PHP 7。*“ $ variables替换”是最快的方法:
$message = "The request {$request} has {$n} errors";
您可以自己证明:
$request = "XYZ";
$n = "0";
$mtime = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$message = "The request {$request} has {$n} errors";
}
$ctime = microtime(true);
echo '
"variable $replacement timing": '. ($ctime-$mtime);
$request = "XYZ";
$n = "0";
$mtime = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$message = 'The request '.$request.' has '.$n.' errors';
}
$ctime = microtime(true);
echo '
"concatenation" . $timing: '. ($ctime-$mtime);
$request = "XYZ";
$n = "0";
$mtime = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$message = sprintf('The request %s has %d errors', $request, $n);
}
$ctime = microtime(true);
echo '
sprintf("%s", $timing): '. ($ctime-$mtime);
PHP 7.3.5 的结果:
“可变$替换时间”:0.091434955596924
“串联”。 $ timing:0.11175799369812
sprintf(“%s”,$ timing):0.17482495307922
可能您已经发现了一些建议,例如“使用sprintf代替双引号中包含的变量,它快10倍左右”。 What are some good PHP performance tips?
我看到这是事实,但是有一天。即在 PHP 5.2。*
之前这里是 PHP 5.1.6 时代的一个示例:
“可变的$替换时间”:0.67681694030762
“串联”。 $ timing:0.24738907814026
sprintf(“%s”,$ timing):0.61580610275269
答案 5 :(得分:0)
最初考虑单个变量赋值的上下文时,第一个是最快的,可以通过查看各种基准来看到。也许,使用核心PHP函数的sprintf风格可以允许更多可扩展的代码,并且可以更好地优化opcache或apc等字节码级缓存机制。换句话说,当使用sprintf方法时,特定大小的应用程序可以使用更少的代码。缓存到RAM中的代码越少,对其他东西或更多脚本的RAM就越多。但是,这只有在您的脚本无法通过评估适当放入RAM时才会有用。