Benchmarking Say

ambs on 2008-04-10T21:45:54

This is strange... use.perl doesn't have Perl as a Journal Topic. Anyway, I think I wrote about this previously, but now I performed some more tests, and thus, here goes some new results. The idea is to compare the new say function to the print function with a new line at the end of the string. To test this, I used the Benchmark module, and two groups of functions: functions that print a string, and functions that print a string with interpolated variables (a scalar and an array).

The four benchmarked functions were:

our $var1 = "!";
our @var2 = qw!Hello World!;

sub print_hello { print "Hello World!\n"; }

sub say_hello { say "Hello World!"; }

sub print_hello_vars { print "@var2$var1\n"; }

sub say_hello_vars { say "@var2$var1"; }

The number of iterations was 10,000,000. Given that all these functions print to the standard output, I redirected the output to a temporary file. Also, and to raise the quality of the test, I ran this benchmark three times.

Now on the results. Do you have any idea of the ordering? Well, first the results were not always the same: say and print swap positions some time. In any case, interpolating on a say is faster, it seems. Check for yourself the three test results:

                      Rate    printI     sayI    print      say
printInterpolate 1587302/s        --     -18%     -67%     -70%
sayInterpolate   1945525/s       23%       --     -60%     -63%
print            4807692/s      203%     147%       --      -8%
say              5208333/s      228%     168%       8%       --

printInterpolate 1647446/s        --     -10%     -66%     -68%
sayInterpolate   1828154/s       11%       --     -62%     -64%
say              4830918/s      193%     164%       --      -6%
print            5128205/s      211%     181%       6%       --

printInterpolate 1652893/s        --     -10%     -67%     -68%
sayInterpolate   1831502/s       11%       --     -64%     -64%
say              5076142/s      207%     177%       --      -1%
print            5102041/s      209%     179%       1%       --


redirecting to a temp file?!

RGiersig on 2008-04-11T13:18:36

better redirect to /dev/null to get consistent results...

Re:redirecting to a temp file?!

ambs on 2008-04-11T13:31:54

My problem is that cmp_these command from Benchmark prints the results to STDOUT. Probably I should complain to the author and submit a patch :)

Or probably I didn't RTFM till the end, and there is an option for that :)

Incomplete benchmark

bart on 2008-04-13T07:55:57

You're not comparing to:
  1. print "Hello World!";
    with $\ set to "\n"
  2. printf

Re:Incomplete benchmark

ambs on 2008-04-13T13:06:32

Hi, Bart.

I think that printf is an interesting test.

Regarding the first one: say is replacing the usual print "foo\n". You know, normally people do not change $\ just to print a new line.

But I might try that. Thanks for the hint! :)

Re:Incomplete benchmark

bart on 2008-04-14T20:23:10

You know, normally people do not change $\ just to print a new line.
Well... I am. I'm not going to change it for every print statement, but if I need a newline appended for (virtually) all print statements, then I'll simply set $\ once (for example by using the -l command line switch — it works on the shebang line too), and just use plain print.

For example: to print a tab separated text data file, I simply do:

{
  local($\, $,) = ("\n", "\t");
  print @$_ foreach @AoA;
}
which, qua readability, beats

print join("\t", @$_)."\n" foreach @AoA;
hands down.

For the rare occasions that I don't need the newline, I then do

{
  local $\;
  print @foo;
}

As perldoc -f say says:

say LIST is simply an abbreviation for { local $\ = "\n"; print LIST }.
my idiom might actually be reasonably fast by comparison.