Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks:

I am using Benchmark to do some simple tests, for example:

#!/usr/bin/env perl use strict; use warnings; use Benchmark qw[cmpthese timethese]; my @A = qw[this that these those]; my $result = timethese( -5, { test => sub { print @A }, with_for => sub { print for @A }, with_join=> sub { print join '', @A }, }); cmpthese($result); __END__

Problems is that the test functions contain print statement which clogged up my screen when the script is running. Is there some ways to silence these outputs??

Many thanks Lihao

Replies are listed 'Best First'.
Re: Question with Benchmark.pm
by moritz (Cardinal) on Dec 13, 2007 at 08:03 UTC
    There are a couple of ways:

    1) Don't use print in the first place

    2) close STDOUT and open it again, sending it to /dev/null this time (assuming a unixy environment. (And print the benchmark to STDERR, if this isn't done already)

    3) work around your problem by running perl script.pl|tail

    Note that I/O is usually rather slow (compared to other operations), so changing I/O behaviour means changing your benchmark results.

Re: Question with Benchmark.pm
by poolpi (Hermit) on Dec 13, 2007 at 15:13 UTC
    It works like this :
    #!/usr/bin/perl use strict; use warnings; use Benchmark qw[cmpthese timethese]; my @A = qw[this that these those]; my $result; open my $null, '>', '/dev/null' or die; $result = timethese( -5, { test => sub { print {$null} "@A" }, with_for => sub { print {$null} $_ for @A }, with_join => sub { print {$null} join '', @A }, } ); cmpthese( $result, 'none' );

    OUTPUT : Benchmark: running test, with_for, with_join for at least 2 CPU second +s... test: 3 wallclock secs ( 2.03 usr + 0.01 sys = 2.04 CPU) @ 64 +2509.31/s (n=1310719) with_for: 1 wallclock secs ( 2.14 usr + 0.00 sys = 2.14 CPU) @ 49 +4696.26/s (n=1058650) with_join: 2 wallclock secs ( 2.16 usr + 0.00 sys = 2.16 CPU) @ 93 +5679.63/s (n=2021068)
    HTH,
    PooLpi

      Hi, guys:

      Thank you so much for your time and suggestions, I finally used PooLpi's solution which looks easy to implement, and I will remember the potential side-effects of "use Benchmark" under IO

      BTW. I also came up with another way: what about putting the running script into the background and then print the result into an external tmp file or whatever, i.e.(with my original script, under bash, Linux for sure)

      stty tostop perl mytest.pl > result.txt & tail -n4 result.txt

      Any side effects with this approach?? Thanks

      Best,

      Lihao(XC)

Re: Question with Benchmark.pm
by KurtSchwind (Chaplain) on Dec 13, 2007 at 13:56 UTC

    Why not just write to a dummy file. I kind of like this a hair better than writting to dev null or monkeying around with stdout. This would be a very fast change.

    open my $fh, '>','delete.this.later' or die ("Unable to open temp file + : $!"); ... my $result = timethese ( -5, { test => sub { print $fh @A }, ...

    And then just delete the file afterword. Sure you'll introduce a bit of Disk IO, but it's the same DiskIO for all of your test threads, so it should wash out in terms of a comparison.

    --
    I used to drive a Heisenbergmobile, but every time I looked at the speedometer, I got lost.
      Sure you'll introduce a bit of Disk IO, but it's the same DiskIO for all of your test threads, so it should wash out in terms of a comparison.

      Are you sure? The example data is far less than the size of a buffer, so won't Perl fill up a buffer and only then write it? That pattern will be predictable but it won't be uniform across those files.

      Benchmarking is difficult; IO doubly so.