php 将两个字符串相加的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/695124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to add two strings together?
提问by Pim Jager
I read somewehere (I thought on codinghorror) that it is bad practice to add strings together as if they are numbers, since like numbers, strings cannot be changed. Thus, adding them together creates a new string. So, I was wondering, what is the best way to add two strings together, when focusing on performance?
我在某处读到(我想到了codinghorror)说将字符串加在一起就像数字一样是不好的做法,因为像数字一样,字符串不能改变。因此,将它们加在一起会创建一个新字符串。所以,我想知道,在关注性能时,将两个字符串加在一起的最佳方法是什么?
Which of these four is better, or is there another way which is better?
这四个中哪个更好,或者有另一种更好的方法?
//Note that normally at least one of these two strings is variable
$str1 = 'Hello ';
$str2 = 'World!';
$output1 = $str1.$str2; //This is said to be bad
$str1 = 'Hello ';
$output2 = $str1.'World!'; //Also bad
$str1 = 'Hello';
$str2 = 'World!';
$output3 = sprintf('%s %s', $str1, $str2); //Good?
//This last one is probaply more common as:
//$output = sprintf('%s %s', 'Hello', 'World!');
$str1 = 'Hello ';
$str2 = '{a}World!';
$output4 = str_replace('{a}', $str1, $str2);
Does it even matter?
它甚至重要吗?
采纳答案by Ed S.
You are always going to create a new string whe concatenating two or more strings together. This is not necessarily 'bad', but it can have performance implications in certain scenarios (like thousands/millions of concatenations in a tight loop). I am not a PHP guy, so I can't give you any advice on the semantics of the different ways of concatenating strings, but for a single string concatenation (or just a few), just make it readable. You are not going to see a performance hit from a low number of them.
当将两个或多个字符串连接在一起时,您总是要创建一个新字符串。这不一定是“坏的”,但它在某些情况下可能会影响性能(例如紧密循环中的数千/数百万级联)。我不是 PHP 专家,因此我无法就连接字符串的不同方式的语义给您任何建议,但是对于单个字符串连接(或仅几个),只需使其可读即可。您不会看到少数人对性能的影响。
回答by Patrick Glandien
String Concatenation with a dot is definitely the fastest one of the three methods. You will always create a new string, whether you like it or not. Most likely the fastest way would be:
带点的字符串连接绝对是三种方法中最快的一种。无论您喜欢与否,您将始终创建一个新字符串。最有可能的最快方法是:
$str1 = "Hello";
$str1 .= " World";
Do not put them into double-quotes like $result = "$str1$str2";as this will generate additional overhead for parsing symbols inside the string.
不要将它们放入双引号中,$result = "$str1$str2";因为这会产生额外的开销来解析字符串中的符号。
If you are going to use this just for output with echo, then use the feature of echo that you can pass it multiple parameters, as this will not generate a new string:
如果您只是将它用于带有 echo 的输出,那么请使用 echo 的功能,您可以向它传递多个参数,因为这不会生成新的字符串:
$str1 = "Hello";
$str2 = " World";
echo $str1, $str2;
For more information on how PHP treats interpolated strings and string concatenation check out Sarah Goleman's blog.
有关 PHP 如何处理内插字符串和字符串连接的更多信息,请查看 Sarah Goleman 的博客。
回答by Aleksandr Makov
Here's the quick and dirty test code, to understand the performance bottlenecks.
这是快速而肮脏的测试代码,以了解性能瓶颈。
Single concat:
单连接:
$iterations = 1000000;
$table = 'FOO';
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = sprintf('DELETE FROM `%s` WHERE `ID` = ?', $table);
}
echo 'single sprintf,',(microtime(true) - $time)."\n";
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = 'DELETE FROM `' . $table . '` WHERE `ID` = ?';
}
echo 'single concat,',(microtime(true) - $time)."\n";
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = "DELETE FROM `$table` WHERE `ID` = ?";
}
echo 'single "$str",',(microtime(true) - $time)."\n";
I get these results:
我得到这些结果:
single sprintf,0.66322994232178
single concat,0.18625092506409 <-- winner
single "$str",0.19963216781616
Many concats (10):
许多连接(10):
$iterations = 1000000;
$table = 'FOO';
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = sprintf('DELETE FROM `%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` WHERE `ID` = ?', $table, $table, $table, $table, $table, $table, $table, $table, $table, $table);
}
echo 'many sprintf,',(microtime(true) - $time)."\n";
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = 'DELETE FROM `' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '`,`' . $table . '` WHERE `ID` = ?';
}
echo 'many concat,',(microtime(true) - $time)."\n";
$time = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$sql = "DELETE FROM `$table`,`$table`,`$table`,`$table`,`$table`,`$table`,`$table`,`$table`,`$table`,`$table` WHERE `ID` = ?";
}
echo 'many "$str",',(microtime(true) - $time)."\n";
Results:
结果:
many sprintf,2.0778489112854
many concats,1.535336971283
many "$str",1.0247709751129 <-- winner
As conclusion, it becomes obvious that single concat via dot (.) char is the fastest. And for cases, when you've got many concats, the best performing method is using direct string injection via "injection: $inject"syntax.
作为结论,很明显,通过点 (.) 字符的单连接是最快的。对于这种情况,当您有很多 concat 时,性能最好的方法是通过"injection: $inject"语法使用直接字符串注入。
回答by Toby Allen
Unless its really large amount of text it really doesnt matter.
除非它的文本量非常大,否则它真的无关紧要。
回答by ya23
It doesn't matter unless used in a looong loop. In usual cases focus on code readability, even if you lost several processor cycles.
除非在 looong 循环中使用,否则没关系。通常情况下,重点关注代码可读性,即使您丢失了几个处理器周期。
Example 1 and 2are similar, I don't think there should be much difference, this would be the fastes of all. No. 1 might be slightly faster.
例1和例2很相似,我认为应该没有太大区别,这就是所有的斋戒。1 号可能稍微快一点。
Example 3will be slower, as sprintf format ('%s %s') needs to be parsed.
示例 3会更慢,因为需要解析 sprintf 格式 ('%s %s')。
Example 4does the replace, which involves searching within a string - additional thing to do, takes more time.
示例 4执行替换操作,这涉及在字符串中进行搜索 - 需要做的其他事情需要更多时间。
But firstly, is concatenating strings a performance problem? It's very unlikely, you should profile code to measure how much time does it take to run it. Then, replace the concatenating method with a different one and time again.
但首先,连接字符串是一个性能问题吗?不太可能,您应该分析代码以测量运行它需要多长时间。然后,一次又一次地用不同的方法替换连接方法。
If you identify it as a problem, try googling for php string builder class (there are some to be found) or write your own.
如果您将其确定为问题,请尝试使用谷歌搜索 php 字符串构建器类(有一些可以找到)或编写您自己的。
回答by PhiLho
As the others said, $str1 . $str2is perfectly OK in most cases, except in (big) loops.
Note that you overlook some solutions:
正如其他人所说,$str1 . $str2在大多数情况下是完全可以的,除了(大)循环。
请注意,您忽略了一些解决方案:
$output = "$str1$str2";
and for large number of strings, you can put them in an array, and use implode() to get a string out of them.
对于大量字符串,您可以将它们放在一个数组中,然后使用 implode() 从中获取一个字符串。
Oh, and "adding strings" sounds bad, or at least ambiguous. In most languages, we prefer to speak of string concatenation.
哦,“添加字符串”听起来很糟糕,或者至少是模棱两可的。在大多数语言中,我们更喜欢谈论字符串连接。
回答by Dave Houlbrooke
Found this post from Google, and thought I'd run some benchmarks, as I was curious what the result would be. (Benchmarked over 10,000 iterations using a benchmarker that subtracts its own overhead.)
从谷歌找到这篇文章,并认为我会运行一些基准测试,因为我很好奇结果会是什么。(使用减去自身开销的基准测试器对超过 10,000 次迭代进行基准测试。)
Which 2 strings 10 strings 50 strings
----------------------------------------------------------------
$a[] then implode() 2728.20 ps 6.02 μs 22.73 μs
$a . $a . $a 496.44 ps 1.48 μs 7.00 μs
$b .= $a 421.40 ps ★ 1.26 μs 5.56 μs
ob_start() and echo $a 2278.16 ps 3.08 μs 8.07 μs
"$a$a$a" 482.87 ps 1.21 μs ★ 4.94 μs ★
sprintf() 1543.26 ps 3.21 μs 12.08 μs
So there's not much in it. Probably good to avoid sprintf()and implode()if you need something to be screaming fast, but there's not much difference between all the usual methods.
所以里面的东西不多。也许很好地避免sprintf()和implode()如果你需要的东西是尖叫快,但不是通常的方法之间的所有太大的区别。
回答by ppostma1
there are 3 types of string joining operations.
有 3 种类型的字符串连接操作。
Concatenate, take 2 string, allocate memory size length1+length2 and copy each into the new memory. quickest for 2 strings. However, concatenating 10 strings then requires 9 concat operations. The memory used is the 1st string 10 times, 2nd string 10 times, 3rd string 9 times, 4th string 8 times, etc. Runs X+1 +(X-1)*2 operations using more memory each cycle.
连接,取2个字符串,分配内存大小length1+length2,然后将每个复制到新的内存中。最快的 2 个字符串。但是,连接 10 个字符串需要 9 个连接操作。使用的内存是第 1 个字符串 10 次、第 2 个字符串 10 次、第 3 个字符串 9 次、第 4 个字符串 8 次,等等。运行 X+1 +(X-1)*2 次操作,每个周期使用更多内存。
sprintf (array_merge, join, etc), take all the strings together, sum their length, allocate a new string of size sum, then copy each string into its respective place. memory used is 2*length of all initial strings, and operations is 2*X (each length, each copy)
sprintf(array_merge、join 等),将所有字符串放在一起,将它们的长度相加,分配一个大小为 sum 的新字符串,然后将每个字符串复制到其各自的位置。使用的内存是所有初始字符串的2*长度,操作是2*X(每个长度,每个副本)
ob (output buffer) allocate a generic 4k chunk and copies each string to it. memory 4k + each initial string, operations = 2 + X. (start, end, each copy)
ob(输出缓冲区)分配一个通用的 4k 块并将每个字符串复制到它。内存 4k + 每个初始字符串,操作 = 2 + X。(开始,结束,每个副本)
Pick your poison. OB is like using a memory atom bomb to join 2 small strings, but is very effective when there are many joins, loops, conditions or the additions are too dynamic for a clean sprintf. concat is the most efficient to join a few fixed strings, sprintf which works better for building a string out of fixed values at one time.
选择你的毒药。OB 就像使用内存原子弹来连接 2 个小字符串,但是当有很多连接、循环、条件或添加对于干净的 sprintf 来说太动态时非常有效。concat 是连接几个固定字符串最有效的方法,sprintf 可以更好地一次从固定值构建字符串。
I don't know which routine php uses in this situation: "$x $y $z", might just be reduced to an inline $x . " " . $y . " " . $z
我不知道在这种情况下 php 使用哪个例程:“$x $y $z”,可能只是减少为内联 $x 。“ ”。$y 。“ ”。$z
回答by DisgruntledGoat
The advice you have read may have been related to the echofunction, for which it's quicker to use commas, eg:
您阅读的建议可能与echo函数有关,为此使用逗号会更快,例如:
echo $str1, $str2;
Another approach is to build up a string in a variable (eg using the . operator) then echo the whole string at the end.
另一种方法是在变量中构建一个字符串(例如使用 . 运算符),然后在末尾回显整个字符串。
You could test this yourself using the microtime function (you'll need to make a loop that repeats eg 1,000 or 100,000 times to make the numbers significant). But of the four you posted, the first one is likely to be the fastest. It's also the most readable - the others don't really make sense programmatically.
您可以使用 microtime 函数自行测试(您需要创建一个循环,例如重复 1,000 或 100,000 次以使数字有意义)。但是在您发布的四个中,第一个可能是最快的。它也是最易读的——其他的在编程上并没有真正的意义。
回答by shadanan
I'm not a PHP guru, however, in many other languages (e.g. Python), the fastest way to build a long string out of many smaller strings is to append the strings you want to concatenate to a list, and then to join them using a built-in join method. For example:
我不是 PHP 高手,但是,在许多其他语言(例如 Python)中,从许多较小的字符串中构建长字符串的最快方法是将要连接的字符串附加到列表中,然后加入它们使用内置的连接方法。例如:
$result = array();
array_push("Hello,");
array_push("my");
array_push("name");
array_push("is");
array_push("John");
array_push("Doe.");
$my_string = join(" ", $result);
If you are building a huge string in a tight loop, the fastest way to do it is by appending to the array and then joining the array at the end.
如果你在一个紧密的循环中构建一个巨大的字符串,最快的方法是附加到数组,然后在最后加入数组。
Note: This entire discussion hinges on the performance of an array_push. You need to be appending your strings to a listin order for this to be effective on very large strings. Because of my limited exposure to php, I'm not sure if such a structure is available or whether php's array is fast at appending new elements.
注意:整个讨论都取决于 array_push 的性能。您需要将字符串附加到列表中,以便对非常大的字符串有效。由于我对 php 的接触有限,我不确定这样的结构是否可用,或者 php 的数组是否能快速添加新元素。

