in reply to Various ways to concatenating an array of strings

I'd be inclined to use join even if it were somewhat slower. However, my guess is that join is faster and actually, a benchmark bears that out:

use strict; use warnings; use Benchmark qw(cmpthese); my @strings = qw( xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz ppppppppppppppppppppppppppppppppppppppppppppppppppppppppp qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr sssssssssssssssssssssssssssssssssssssssssssssssssssssssss ttttttttttttttttttttttttttttttttttttttttttttttttttttttttt ); cmpthese (-1, { join => sub {join '', @strings}, pack => sub {pack("a*" x ($#strings + 1), @strings)}, } );

Prints:

Rate pack join pack 452302/s -- -58% join 1073851/s 137% --

DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: Various ways to concatenating an array of strings
by hawtin (Prior) on Mar 30, 2006 at 19:49 UTC

    As I said in my original post I rejected join() for some good reason months ago. All your reply says is that join is the most obvious solution (which I agree it is), but it didn't work in my case.

    Thank you for your input but your test of course proves nothing, my issue was with thousands of differently sized strings not 8 strings the same size. If I rewrite your test as:

    use strict; use warnings; use Benchmark qw(cmpthese); my @strings; for(my $i=0;$i<1000;$i++) { $strings[$i] = (sprintf("%06d",$i)) x rand(1000); } my $asign1; my $asign2; cmpthese (-1, { pack => sub {$asign2 = pack("a*" x($#strings + 1),@strings)}, join => sub {$asign1 = join '', @strings}, } );

    Then the results are:

    Rate join pack join 108/s -- -21% pack 137/s 27% --

    Having played with this I now recall that the efficiency problem was not with speed but with memory usage. Under some pathalogical cases the join was consuming vast quantities of memory (that was under a previous version of Perl and maybe I should study it again).

    So thank you for helping me illustrate that pack is quicker than join (in some cases) :-)

      First off, I don't like that rand there - it makes things much more difficult to replicate. So, after running your test as-is a few times, I went and just changed "rand(1000)" to "1000" and reran it. I got slightly more consistant answers when the strings where consistantly sized.

      At no time have I had pack outperform join. Although my CPU seems to be a bit slower than yours ... I never got over 100 runs per second.

      As-is: Rate pack join pack 80.0/s -- -15% join 93.7/s 17% -- Always 1000: Rate pack join pack 46.0/s -- -8% join 50.0/s 9% -- x $i rather than x 1000 or x rand(1000): Rate pack join pack 74.0/s -- -14% join 86.0/s 16% --
      Since it seems that the longer the strings, the closer they were, I tried 10,000.
      Rate pack join pack 5.66/s -- -5% join 5.94/s 5% --
      It doesn't seem that I can get pack outperforming join on this issue. And that's probably despite being utf-8 aware...

      Tests above were run on a threaded perl 5.8.7 on Linux

      According to your Benchmarks, join is taking 0.009 seconds to execute compared to pack's 0.007. Are you sure you need those extra 2 milliseconds?

        As I said the speed was not critical, the fact that some pathalogical cases join consumed so much virtual memory that the machine died was sufficiently "inconvinient" to make me seek an alternative (even an obscure one).