php: output[] w/ join vs $output .=

拜拜、爱过 提交于 2019-12-13 13:48:29

问题


I'm modifying some code in which the original author built a web page by using an array thusly:

 $output[]=$stuff_from_database;
 $output[]='more stuff';
 // etc
 echo join('',$output);

Can anyone think of a reason why this would be preferable (or vice versa) to:

 $output =$stuff_from_database;
 $output .='more stuff';
 // etc
 echo $output;

回答1:


It was probably written by someone who comes from a language where strings are immutable and thus concatenation is expensive. PHP is not one of them as the following tests show. So the second approach is performance wise, better. The only other reason that I can think of to use the first approach is to be able to replace some part of the array with another, but that means to keep track of the indexes, which is not specified.

~$ cat join.php
<?php

for ($i=0;$i<50000;$i++) {
$output[] = "HI $i\n";
}

echo join('',$output);
?>


~$ time for i in `seq 100`; do php join.php >> outjoin ; done

real    0m19.145s
user    0m12.045s
sys     0m3.216s

~$ cat dot.php
<?php

for ($i=0;$i<50000;$i++) {
$output.= "HI $i\n";
}

echo $output;
?>


~$ time for i in `seq 100`; do php dot.php >> outdot ; done

real    0m15.530s
user    0m8.985s
sys     0m2.260s



回答2:


This is a little off topic, but

$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;

Is far slower than:

echo = $stuff_from_database;
echo 'more stuff';

In fact, the fastest way to build a string in PHP is:

ob_start();
echo = $stuff_from_database;
echo 'more stuff';
$output = ob_get_contents();
ob_end_clean();

Due to the way that output buffers work and such, it is the fastest way to build a string. Obviously you would only do this if you really need to optimize sting building as it is ugly and doesn't lead to easy reading of the code. And everyone one knows that "Premature optimization is the root of all evil".




回答3:


Again, a little bit off topic (not very far), but if you were aiming to put something between the array items being output, then if there was only a few lines to concatenate, join(', ', $output) would do it easily and quickly enough. This would be easier to write, and avoids having to check for the end of the list (where you would not want a trailing ',').

For programmer time, as it is on the order of 1000's of times more expensive than a cpu cycle, I'd usually just throw it into a join if it wasn't going to be run 10,0000+ times per second.

Post-coding micro-optimisation like this is very rarely worth it in terms of time taken vs cpu time saved.




回答4:


<!-- Redacted Previous Comment -->

It would appear I had an error in my code so i was doing a no-op and forgot to check.

It would appear Contary to previous testing, and reading previous blogs on the topic, the following conclusions are actually ( tested ) untrue at least for all variants of the above code I can permute.

  1. UNTRUE: String interpolation is slower than string concatenation. (!)
  2. UNTRUE: SprintF is fastest.

In actual tests, Sprintf was the slowest and interpolation was fastest

PHP 5.2.6-pl7-gentoo (cli) (built: Sep 21 2008 13:43:03) 
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans

It may be conditional to my setup, but its still odd. :/




回答5:


I think the fastest way to do it is with echoes. It's not as pretty and probably not enough faster to be worth the cost in readability.

echo $stuff_from_database
   , 'more stuff'
   , 'yet more'
   // etc
   , 'last stuff';



回答6:


The bottom will reallocate the $output string repeatedly, whereas I believe the top will just store each piece in an array, and then join them all at the end. The original example may end up being faster as a result. If this isn't performance sensitive, then I would probably append, not join.




回答7:


This part of the code is not performance sensitive; it is used to format and display a user's shopping cart info on a low-traffic website. Also, the array (or string) is built from scratch each time and there is no need to address or search for specific elements. It sounds like the array is somewhat more efficient, but I guess it doesn't matter either way for this use. Thanks for all of the info!




回答8:


If you're generating a list (e.g. a shopping cart), you should have some code that generates the HTML from each entry fetched from the database.

for ($prod in $cart)
{
  $prod->printHTML();
}

Or something like that. That way, the code becomes a lot cleaner. Of course, this assumes that you've got nice code with objects, rather than a whole moronic mess like my company does (and is replacing).




回答9:


It has already been said, but I think a distinct answer will help.

The original programmer wrote it that way because he thought it was faster. In fact, under PHP 4, it really was faster, especially for large strings.




回答10:


If joined with implode() or join(), PHP is able to better optimize that. It goes through all strings in your list, calculates the length and allocates the required space and fills the space. In comparison with the ".=" it has to constantly free() and malloc() the space for the string.



来源:https://stackoverflow.com/questions/111282/php-output-w-join-vs-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!