TTaJTa4
TTaJTa4

Reputation: 840

Checking the performance of two ways to append string in Perl

I can use the two following ways in Perl:

my $str = "hello";
my $o1 = $str." world";
my $o2 = "$str world";

They do the same thing, although I was wondering if they are the same when speaking about performance. How can I check it? is there a special online tool?

Upvotes: 0

Views: 254

Answers (3)

ikegami
ikegami

Reputation: 386471

They're not merely similar; they both produce exactly the same code.

$ for v in 5.10 5.12 5.14 5.16 5.18 5.20 5.22 5.24 5.26 5.28
do
   diff -u \
      <( "$v"t/bin/perl -MO=Concise,-exec -e'my $x = $str . " world"' 2>&1 ) \
      <( "$v"t/bin/perl -MO=Concise,-exec -e'my $x = "$str world"'    2>&1 ) \
      && echo "$v: identical" \
      || echo "$v: different"
done
5.10: identical
5.12: identical
5.14: identical
5.16: identical
5.18: identical
5.20: identical
5.22: identical
5.24: identical
5.26: identical 
5.28: identical 

As such, there will be no difference in performance.

By the way, you're not thinking straight if you're wondering about the performance difference of those two; you should be thinking about readability/maintainability.

Upvotes: 3

Dave Cross
Dave Cross

Reputation: 69314

Benchmark is the way to do this.

The two methods you're describing are called concatenation and interpolation, so we'll use those names as labels in the test.

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark;

my $str = 'hello';

# Run this two subroutines for at least 3 CPU seconds.
# That "negative seconds" parameter is possibly the worst
# interface in all of Perl!
timethese(-3, {
  concat => sub { $str . ' world' },
  interp => sub { "$str world" },
});

And the results...

$ perl benchmark
Benchmark: running concat, interp for at least 3 CPU seconds...
    concat:  4 wallclock secs ( 3.16 usr +  0.00 sys =  3.16 CPU) @ 32680513.61/s (n=103270423)
    interp:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 29918605.90/s (n=96337911)

Concatenation is slightly faster [Note: as pointed out in the comments, that's note really true - any differences are well within the margin of error for these tests]. But note that we needed to run around a hundred million tests in order to find this tiny difference. So I don't think you really need to worry here.

Upvotes: 8

choroba
choroba

Reputation: 242038

Benchmark is usually used to benchmark code. It's good to also test that the code being benchmarked gives the same output, so I included Test::More.

#! /usr/bin/perl
use warnings;
use strict;

use Benchmark qw{ cmpthese };

my $var = join "", 'a' .. 'z';
my $string = uc $var;

my $dot = "\$string . ' $var'";
my $dq  = qq("\$string $var");

use Test::More tests => 1;
is  eval $dot,
    eval $dq,
    'same';

cmpthese(-3, {
         dot => $dot,
         dq  => $dq,
});

The results from repeated runs seem random, so the difference is probably negligible:

1..1
ok 1 - same
          Rate dot  dq
dot 19583087/s  -- -6%
dq  20725520/s  6%  --

1..1
ok 1 - same
          Rate  dq dot
dq  18925046/s  -- -7%
dot 20246124/s  7%  --

Upvotes: 3

Related Questions