printing lists versus concat strings? a little nibble of a benchmark

Please check out the comments to see more information about this topic.

Going to put this out there because I saw some code the other day that printed comma separated strings and scalars, and it got me curious about how expensive it was to print a list of items, rather than concatenating them into a string and passing that to print.

I’ll let the code speak for itself:

 my $x = 'test';
 my $r = timethese(
 10000000,
 { 
 'commaprint'    => sub { print STDERR 'test', 'test', 'test', 'test', 'test', 'test'; },
 'varcommaprint' => sub { print STDERR $x, $x, $x, $x, $x, $x; },
 'interpprint'   => sub { print STDERR "$x $x $x $x $x $x"; },
 'concatprint'   => sub { print STDERR 'test' . 'test' . 'test' . 'test' . 'test' . 'test'; }, 
 'singleprint'   => sub { print STDERR 'test'; },
} );

And the result on my laptop:

commaprint: 33 wallclock secs (12.46 usr + 19.77 sys = 32.23 CPU) @ 310269.93/s (n=10000000)
varcommaprint: 32 wallclock secs (12.76 usr + 19.74 sys = 32.50 CPU) @ 307692.31/s (n=10000000)
interpprint: 10 wallclock secs ( 7.44 usr +  3.68 sys = 11.12 CPU) @ 899280.58/s (n=10000000)
concatprint:  6 wallclock secs ( 3.02 usr +  3.58 sys =  6.60 CPU) @ 1515151.52/s (n=10000000)
singleprint:  6 wallclock secs ( 2.97 usr +  3.52 sys =  6.49 CPU) @ 1540832.05/s (n=10000000)

I’m not completely surprised by the result, but I would’t want to speculate about what’s going on under the covers without spending time studying the perl code. For now this will just have to leave this out there as something to consider in the future.

 

Post to Twitter Post to Digg Post to Facebook Send Gmail Post to LinkedIn Post to Reddit Post to StumbleUpon

About Tom
I work in a healthcare technology startup. These days, I attempt to code in Perl, and this blog is about the Wild Perl we write, startup life, and many other things.

7 Responses to printing lists versus concat strings? a little nibble of a benchmark

  1. Chas. Owens says:

    Your concatprint test is not fair. The concatenation occurs only once because Perl folds constants:


    perl -MO=Deparse -e '$a = "a" . "b"; $b = 5 + 10;'

    a better benchmark is


    #!/usr/bin/perl

    use strict;
    use warnings;

    use Benchmark;
    use File::Spec;

    open my $fh, ">", File::Spec->devnull
        or die "could not open bit bucket (", File::Spec->devnull, "): $!";

    my $x = 'a';
    my %subs = (
        comma => sub { print $fh $x, $x, $x, $x, $x, $x; },
        string => sub { print $fh "$x$x$x$x$x$x"; },
        concat => sub { print $fh $x . $x . $x . $x . $x . $x; },
    );

    Benchmark::cmpthese -1, \%subs;

    Which produces


                Rate concat comma string
    concat 2143658/s -- -4% -4%
    comma 2226951/s 4% -- -0%
    string 2234181/s 4% 0% --

    From this we can see that there is practically no difference between the styles.

  2. Tom says:

    Hi Chas,

    Thanks for taking the time to reply to my post, and to point out the lifting Perl does for constant creation.

    When I run your benchmark I get similar results, and if I run it for longer I see results like:

    Rate concat string comma
    concat 3226888/s -- -2% -10%
    string 3301053/s 2% -- -8%
    comma 3572287/s 11% 8% --

    I’m not sure if these results are some artifact of the way I’m running the tests. I’m curious if comma separated printing could take less time because it would skip the string creation.

  3. Chas. Owens says:

    I think it is just noise. I ran the benchmark with -20 and got

    nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Ratenbsp;concatnbsp;stringnbsp;nbsp;comma
    concatnbsp;1867761/snbsp;nbsp;nbsp;nbsp;nbsp;--nbsp;nbsp;nbsp;nbsp;-8%nbsp;nbsp;nbsp;-17%
    stringnbsp;2036189/snbsp;nbsp;nbsp;nbsp;nbsp;9%nbsp;nbsp;nbsp;nbsp;nbsp;--nbsp;nbsp;nbsp;nbsp;-9%
    commanbsp;nbsp;2245308/snbsp;nbsp;nbsp;nbsp;20%nbsp;nbsp;nbsp;nbsp;10%nbsp;nbsp;nbsp;nbsp;nbsp;--

    And then with -50 and got

    nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Ratenbsp;stringnbsp;nbsp;commanbsp;concat
    stringnbsp;1994398/snbsp;nbsp;nbsp;nbsp;nbsp;--nbsp;nbsp;nbsp;nbsp;-0%nbsp;nbsp;nbsp;nbsp;-8%
    commanbsp;nbsp;2002747/snbsp;nbsp;nbsp;nbsp;nbsp;0%nbsp;nbsp;nbsp;nbsp;nbsp;--nbsp;nbsp;nbsp;nbsp;-7%
    concatnbsp;2160460/snbsp;nbsp;nbsp;nbsp;nbsp;8%nbsp;nbsp;nbsp;nbsp;nbsp;8%nbsp;nbsp;nbsp;nbsp;nbsp;--

  4. Chas. Owens says:

    Whoops, that should have been

                Rate concat string  comma
    concat 1867761/s     –    -8%   -17%
    string 2036189/s     9%     –    -9%
    comma  2245308/s    20%    10%     –

                Rate string  comma concat
    string 1994398/s     –    -0%    -8%
    comma  2002747/s     0%     –    -7%
    concat 2160460/s     8%     8%     –

  5. Chas. Owens says:

    durn it, I had blogs that don’t use markdown, one last time:

                Rate concat string  comma
    concat 1867761/s     --    -8%   -17%
    string 2036189/s     9%     --    -9%
    comma  2245308/s    20%    10%     --

                Rate string  comma concat
    string 1994398/s     --    -0%    -8%
    comma  2002747/s     0%     --    -7%
    concat 2160460/s     8%     8%     --

  6. Tom says:

    Thanks Chas!

  7. Alexander Hartmaier (abraxxa) says:

    I thought passing a list should be faster because it doesn’t concat the strings which also requires more memory?!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>