By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,149 Members | 885 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,149 IT Pros & Developers. It's quick & easy.

string concat vs. join/implode

P: n/a

Maybe a stupid question.
-------------------------
1
-------------------------
$str = '';

for($i=0; $i<10; $i++)
$str .= $i;

echo $str;

-------------------------
2
-------------------------
$str = array();

for($i=0; $i<10; $i++)
$str[]= $i;

echo implode('', $str);

-------------------------

I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?

thanks

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 14 '07 #1
Share this Question
Share on Google+
18 Replies


P: n/a
On May 14, 11:27 am, NoWhereMan <nowheremanNOS...@flashmailSPAM.com>
wrote:
Maybe a stupid question.

-------------------------
1
-------------------------
$str = '';

for($i=0; $i<10; $i++)
$str .= $i;

echo $str;

-------------------------
2
-------------------------
$str = array();

for($i=0; $i<10; $i++)
$str[]= $i;

echo implode('', $str);

-------------------------

I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?

thanks

--
NoWhereMan (e.v.)
--http://www.nowhereland.it
--http://flatpress.nowhereland.it
I would say probably not, as (1) is touching each element n times,
whereas (2) is most likely n*ln(n) in the best case. For i=10, it'll
double. implode() probably just runs your (1) again, appending each
element. I'm not entirely sure how the GC operates in PHP or what kind
of performance hit you might take, but it seems like copy-on-write
could make dereference in (1) not happen as often as you may think.

Regards,
Andrew

May 14 '07 #2

P: n/a
NoWhereMan kirjoitti:
Maybe a stupid question.
-------------------------
1
-------------------------
$str = '';

for($i=0; $i<10; $i++)
$str .= $i;

echo $str;

-------------------------
2
-------------------------
$str = array();

for($i=0; $i<10; $i++)
$str[]= $i;

echo implode('', $str);

-------------------------
3:

echo implode('', range(0,9));

(I suppose 2 is eactly the way range() is implemented, so there should
be not much difference...)
I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?
Why don't you benchmark them for comparison? Run both in a loop for
thousands of times and take time for both and check how much memory they
consume. You'll need memory_get_usage(), maybe memory_get_peak_usage()
and microtime().

If I had to guess, I'd say there is no huge difference between
concatenating a char and adding an element to an array, but what will
tip the scale is that you need to use implode in the second version,
that'll create some overhead for the second version.

--
Ra*********@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
May 14 '07 #3

P: n/a
On 14 May 2007 12:05:10 -0700, frugalprogrammer wrote:
I would say probably not, as (1) is touching each element n times,
whereas (2) is most likely n*ln(n) in the best case. For i=10, it'll
double. implode() probably just runs your (1) again, appending each
element. I'm not entirely sure how the GC operates in PHP or what kind
of performance hit you might take, but it seems like copy-on-write
could make dereference in (1) not happen as often as you may think.
interesting, so definitely not a totally stupid one :)

well IIRC I read something about using .join() instead of += in a guide
about optimizing JavaScript (this applies to Java as well, though); I
thought it could be applied to PHP too.

But maybe that involved just single character or number concats

thank you

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 14 '07 #4

P: n/a
On Mon, 14 May 2007 22:14:58 +0300, Rami Elomaa wrote:
Why don't you benchmark them for comparison? Run both in a loop for
thousands of times and take time for both and check how much memory they
consume. You'll need memory_get_usage(), maybe memory_get_peak_usage()
and microtime().

unfortunately the PHP version I've got here has not been compiled with
memory limits... by the way, I've did this quick and dirty concat vs.
implode test with microtime() only.

concat is generally a bit slower than join when strings are small and
iterations are not many (for instance 10) results are about in the order of
8.5E-5 vs. 6.0E-5 so quite a bit :)

by the way as the number of iterations grows and as the length of the
string grows the results are very comparable, so comparable (almost same
values from 0.00025 to 0.00030) that I think loops must have been optimized
in this sense :)

bye

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 14 '07 #5

P: n/a
NoWhereMan wrote:
Maybe a stupid question.
-------------------------
1
-------------------------
$str = '';

for($i=0; $i<10; $i++)
$str .= $i;

echo $str;

-------------------------
2
-------------------------
$str = array();

for($i=0; $i<10; $i++)
$str[]= $i;

echo implode('', $str);

-------------------------

I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?

thanks
I think performance differences are hardly noticeable here, but the
latter method is still far better. In real life we use non-empty
separators and mostly omit the last one: "a" + "b" + "c" -"a,b,c".
implode() does exactly this, with concatenation we will need some ugly
cleanup at the end of the loop.
--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
May 14 '07 #6

P: n/a
NoWhereMan wrote:
well IIRC I read something about using .join() instead of += in a guide
about optimizing JavaScript (this applies to Java as well, though); I
thought it could be applied to PHP too.
The way Javascript deals with strings is entirely different to the way PHP
does. In Javascript, strings are an immutable object, so the += operator
doesn't just concatenate one new string onto an existing string object --
it creates a brand new string object then reassigns the old string object
variable to point to the new object, marking the old object for garbage
collection.

--
Toby A Inkster BSc (Hons) ARCS
http://tobyinkster.co.uk/
Geek of ~ HTML/SQL/Perl/PHP/Python/Apache/Linux
May 14 '07 #7

P: n/a
On May 14, 3:14 pm, Rami Elomaa <rami.elo...@gmail.comwrote:
NoWhereMan kirjoitti:
Maybe a stupid question.
-------------------------
1
-------------------------
$str = '';
for($i=0; $i<10; $i++)
$str .= $i;
echo $str;
-------------------------
2
-------------------------
$str = array();
for($i=0; $i<10; $i++)
$str[]= $i;
echo implode('', $str);
-------------------------

3:

echo implode('', range(0,9));

(I suppose 2 is eactly the way range() is implemented, so there should
be not much difference...)
I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?

Why don't you benchmark them for comparison? Run both in a loop for
thousands of times and take time for both and check how much memory they
consume. You'll need memory_get_usage(), maybe memory_get_peak_usage()
and microtime().

If I had to guess, I'd say there is no huge difference between
concatenating a char and adding an element to an array, but what will
tip the scale is that you need to use implode in the second version,
that'll create some overhead for the second version.

--
Rami.Elo...@gmail.com

"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze
I replaced 10 with 100000 and ran each function through a profiler.
The first one (using concatenation) was approximately 25% faster than
the one using implode().

May 14 '07 #8

P: n/a
On May 15, 12:02 am, ZeldorBlat <zeldorb...@gmail.comwrote:
On May 14, 3:14 pm, Rami Elomaa <rami.elo...@gmail.comwrote:
NoWhereMan kirjoitti:
Maybe a stupid question.
-------------------------
1
-------------------------
$str = '';
for($i=0; $i<10; $i++)
$str .= $i;
echo $str;
-------------------------
2
-------------------------
$str = array();
for($i=0; $i<10; $i++)
$str[]= $i;
echo implode('', $str);
-------------------------
3:
echo implode('', range(0,9));
(I suppose 2 is eactly the way range() is implemented, so there should
be not much difference...)
I suppose the latter will be more performant because there's less work for
the garbage collector, am I right?
Why don't you benchmark them for comparison? Run both in a loop for
thousands of times and take time for both and check how much memory they
consume. You'll need memory_get_usage(), maybe memory_get_peak_usage()
and microtime().
If I had to guess, I'd say there is no huge difference between
concatenating a char and adding an element to an array, but what will
tip the scale is that you need to use implode in the second version,
that'll create some overhead for the second version.
--
Rami.Elo...@gmail.com
"Wikipedia on vähän niinq internetin raamattu, kukaan ei pohjimmiltaan
usko siihen ja kukaan ei tiedä mikä pitää paikkansa." -- z00ze

I replaced 10 with 100000 and ran each function through a profiler.
The first one (using concatenation) was approximately 25% faster than
the one using implode().
I think with the modern Servers that companies use, with usually
enough RAM to go around one shouldn't be too concerned with what the
Garbage Collector does. In my experience, the most important thing to
worry about is speed, as ZeldorBlat demonstrated here. Remember, your
script will be ran on the server for a fraction of a second if it's a
normal web page, and then will most probably not be ran for some time
until the next user hits that page. If you see that this script has a
problem in terms of memory usage, then yes - try and figure out how to
use less memory and be more effective. But if not, rather worry about
speed. Do test like Z did with the profiler and use the fastest.
That's usually also a good indicator of what's best for the GC as
well, 'cause if something runs faster, it generally means that the GC
didn't have to do so much work which would off course take some time
to do. My rule of thumb is:
1) If you run out of memory in your script, start unsetting variables
once you're done with it. If that works, cool!
2) If (1) didn't work, then start benchmarking and see what's taking a
crapload of time, concentrate on making that work faster - usually you
sort out your memory leak / problem out right there and then.
3) If (2) didn't work, admit you're in trouble and look at the script
as a whole - see if you couldn't have done it some other way - think
outside the box on this one then ;-)

May 15 '07 #9

P: n/a
On Mon, 14 May 2007 22:36:46 +0100, Toby A Inkster wrote:
The way Javascript deals with strings is entirely different to the way PHP
does. In Javascript, strings are an immutable object, so the += operator
doesn't just concatenate one new string onto an existing string object --
it creates a brand new string object then reassigns the old string object
variable to point to the new object, marking the old object for garbage
collection.
that's right but in what a PHP string actually differs from a JS string? I
mean, in PHP strings are not objects but primitives, but how are they
internally handled?

I'm not sure they're not garbage collected as, say, arrays; in fact strings
are always array of chars, and arrays are usually passed by reference (in
PHP4 only arrays of arrays do, but there's always copy-on-write).

Of course, I'm not sure, that's why I asked

bye

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 15 '07 #10

P: n/a
On 14 May 2007 15:02:01 -0700, ZeldorBlat wrote:
I replaced 10 with 100000 and ran each function through a profiler.
The first one (using concatenation) was approximately 25% faster than
the one using implode().
nice :)

Could you please repeat the test with a long string isntead of $i?
maybe a $str .= str_pad($i, 10^10 , "___"); so that you have a very long
string? of course not a $str .= "My very long long string"; because the
literal may be evaluated only once, and multi-referenced in the join()
version, resulting in a quicker computation (I think...)

bye
--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 15 '07 #11

P: n/a
On 15 May 2007 00:34:57 -0700, Sarel wrote:
On May 15, 12:02 am, ZeldorBlat <zeldorb...@gmail.comwrote:
I think with the modern Servers that companies use, with usually
enough RAM to go around one shouldn't be too concerned with what the
Garbage Collector does. In my experience, the most important thing to
worry about is speed, as ZeldorBlat demonstrated here.
[...]
That's usually also a good indicator of what's best for the GC as
well, 'cause if something runs faster, it generally means that the GC
didn't have to do so much work which would off course take some time
to do.
yes, that's why I asked. I thought of the GC as an attempt to justify why
the second loops should have been faster, but it seems I wasn't right

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 15 '07 #12

P: n/a
On May 15, 7:14 am, NoWhereMan <nowheremanNOS...@flashmailSPAM.com>
wrote:
On 14 May 2007 15:02:01 -0700, ZeldorBlat wrote:
I replaced 10 with 100000 and ran each function through a profiler.
The first one (using concatenation) was approximately 25% faster than
the one using implode().

nice :)

Could you please repeat the test with a long string isntead of $i?
maybe a $str .= str_pad($i, 10^10 , "___"); so that you have a very long
string? of course not a $str .= "My very long long string"; because the
literal may be evaluated only once, and multi-referenced in the join()
version, resulting in a quicker computation (I think...)

bye

--
NoWhereMan (e.v.)
--http://www.nowhereland.it
--http://flatpress.nowhereland.it
If you post the code for the two functions you want me to compare I'll
be happy to do so and post the results.

May 15 '07 #13

P: n/a
On 15 May 2007 07:25:57 -0700, ZeldorBlat wrote:
If you post the code for the two functions you want me to compare I'll
be happy to do so and post the results.
maybe something along these lines ? I'm not sure how much str_pad should
count but it should take about the same amount of time for both the
functions

-------------------------

function foo($count, $pad) {

$str = '';

for($i=0; $i<$count; $i++)
$str .= str_pad($i, $pad , "___");

return $str;

}

function bar($count, $pad) {

$str = array();

for($i=0; $i<$count; $i++)
$str[]= str_pad($i, $pad , "___");

return implode('', $str);
}
-------------------------

using large $count and $pad

dunno if this is test is valuable... it's the first thing I thought to
generate big different strings, without using a constant and without
randomizing

bye
--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 15 '07 #14

P: n/a
NoWhereMan wrote:
I'm not sure they're not garbage collected as, say, arrays; in fact strings
are always array of chars,
No, they're not. Strings are arrays of characters in C, but not in PHP
where they're a primitive data type -- nothing to do with arrays.

If you need proof:
echo (is_array("Hello")?"Strings are arrays":"Strings are NOT arrays");

--
Toby A Inkster BSc (Hons) ARCS
http://tobyinkster.co.uk/
Geek of ~ HTML/SQL/Perl/PHP/Python/Apache/Linux
May 15 '07 #15

P: n/a
"NoWhereMan" <no**************@flashmailSPAM.comwrote in message
news:1i*******************************@40tude.net. ..
On 14 May 2007 15:02:01 -0700, ZeldorBlat wrote:
>I replaced 10 with 100000 and ran each function through a profiler.
The first one (using concatenation) was approximately 25% faster than
the one using implode().

nice :)

Could you please repeat the test with a long string isntead of $i?
maybe a $str .= str_pad($i, 10^10 , "___"); so that you have a very long
10^10? Surely you mean pow(10,10), not 10 xor 10?

--
Ra*********@gmail.com

"Good tea. Nice house." -- Worf
May 16 '07 #16

P: n/a
On Wed, 16 May 2007 09:16:55 +0300, Rami Elomaa wrote:
>Could you please repeat the test with a long string isntead of $i?
maybe a $str .= str_pad($i, 10^10 , "___"); so that you have a very long

10^10? Surely you mean pow(10,10), not 10 xor 10?
of course :)

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 16 '07 #17

P: n/a
On Tue, 15 May 2007 22:13:23 +0100, Toby A Inkster wrote:
NoWhereMan wrote:
>I'm not sure they're not garbage collected as, say, arrays; in fact strings
are always array of chars,

No, they're not. Strings are arrays of characters in C, but not in PHP
where they're a primitive data type -- nothing to do with arrays.
oc course, what I meant is that *internally* they should be vectors of
chars, as there's no such thing like a primitive string datatype in C

--
NoWhereMan (e.v.)
-- http://www.nowhereland.it
-- http://flatpress.nowhereland.it
May 16 '07 #18

P: n/a
On 16.05.2007 13:32 NoWhereMan wrote:
On Tue, 15 May 2007 22:13:23 +0100, Toby A Inkster wrote:
>NoWhereMan wrote:
>>I'm not sure they're not garbage collected as, say, arrays; in fact strings
are always array of chars,
No, they're not. Strings are arrays of characters in C, but not in PHP
where they're a primitive data type -- nothing to do with arrays.

oc course, what I meant is that *internally* they should be vectors of
chars, as there's no such thing like a primitive string datatype in C
Nor there are "vectors" or "arrays".

--
gosha bine

extended php parser ~ http://code.google.com/p/pihipi
blok ~ http://www.tagarga.com/blok
May 16 '07 #19

This discussion thread is closed

Replies have been disabled for this discussion.