Performance of chained methods.

Paul Fenwick pjf at perltraining.com.au
Wed Oct 30 05:31:45 CST 2002


G'day Scotty,

On Wed, Oct 30, 2002 at 02:48:12PM +1100, Scott Penrose wrote:

> My problem is that each of these can fail. In my particular case I  
> don't care which fail or why, is it ok therefore to do this
> 
> 	my $ref = eval  
> {SomeClass->FirstMethod($param1)->AnotherMethod($param2)- 
> >MoreMethods();};
> 	return undef if ($@);

Looks good to me, especially if you don't care why they fail.  I
would consider it *good* practice, as you end up with cleaner code.
I'm a great fan of code exceptions, rather than requiring
checks every step of the way.

In fact, it's not only cleaner and more programmer friendly, it's
also *faster*, especially for long chains.  On my system, the exceptions
code only uses 8.5 CPU seconds to run the tests below, but the
checking code requires 11.4 CPU seconds.  (800MHz Duron, Perl 5.6.1)

(Hint, on most systems you can pipe this entire message to "perl -x" to run
the same tests.)

#!/usr/bin/perl -w
use strict;

package Foo;

sub bar  { return $_[0]; }
sub baz  { return $_[0]; }
sub bark { return $_[0]; }
sub bath { return $_[0]; }
sub barf { return undef; }

package main;

use Benchmark;

my $foo = bless({},"Foo");

timethese(1_000_000, {
	exceptions => sub {
		eval {
			$foo->bar->baz->bark->bath->barf;
		};
		return undef if ($@);
	},

	checks => sub {
		my $bar  = $foo->bar or return undef;
		my $baz  = $bar->baz or return undef;
		my $bark = $baz->bark or return undef;
		my $bath = $bark->bath or return undef;
		my $barf = $bath->barf or return undef;
	}
});
__END__


Cheers,

	Paul

-- 
Paul Fenwick <pjf at perltraining.com.au> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681



More information about the Melbourne-pm mailing list