How fast is an EVAL String

Scott Penrose scottp at dd.com.au
Sun Apr 25 06:54:14 CDT 2004


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Dudes.

On my home machine, I have found that a method ('data') in our MI::MDO  
is the largest used piece of code on library (6%) so I had a look at  
it. Basically it takes in a key (eg: DC.Title), uses a regular  
expression to turn '.' into '->' and then uses an eval string to turn  
that into the calls on the methods. I wrote a small test case (next  
bit) which shows a comparison between using an eval and iterating  
through the list...

#  
======================================================================== 
======

package Dummy;
use overload
         '""' => '_op_string',
         ;
use vars qw/$AUTOLOAD/;

our $list = [qw/
	DC.Identifier
	SCHNET.Privilige.SINA.Test
	SCHNET.Privilige.SINA.has_micc
	SCHNET.Privilige.SINA.has_mydesktop
	SCHNET.Privilige.SINA.has_blah
	SCHNET.Privilige.SINA.portfolio
	SCHNET.Privilige.SINA.user
	SCHNET.AutoCreate.Folio.make
	SCHNET.AutoCreate.Class
	SCHNET.Mail.Domain
	DC.Title
/];

sub new {
	my ($class) = @_;
	return bless {}, ref($class) || $class;
}

sub data1 {
	my ($this, $key, @rest) = @_;
	unless (defined($key)) {
		return $this->list();
	}
	my $ret = $this;
	eval {
		foreach my $bit (split(/\./, $key)) {
			$ret = $ret->$bit;
		}
	};
	die("Failed with $@") if ($@);
	return $ret;
}

sub data2 {
	my ($this, $key, @rest) = @_;
	unless (defined($key)) {
		return $this->list();
	}
	$key =~ s/\./->/g;
	{
		local $SIG{__DIE__} = sub { die $_[0]; };
		return eval "\$this->$key(\@rest)";
	}
}

sub AUTOLOAD {
	my ($this) = @_;
	return $this;
}

sub _op_string {
	my ($this) = @_;
	return "string";
}

#  
======================================================================== 
======

package main;

my $d = Dummy->new();

use Time::HiRes qw( usleep ualarm gettimeofday tv_interval time );

foreach my $m (qw/data1 data2/) {
	my $start = time;
	for my $count (0..9999) {
		foreach my $id (@$list) {
			my $str = $d->$m($id);
			die "Failed data" unless ("" . $str eq "string");
		}
	}
	my $end = time;
	print "Run Time $m = " . ($end - $start) . "\n";
}


Running this I get between 3 and 5 times speed increase using data1 -  
the iterative approach, rather than the eval.

Something to note.

(output of run of 100,000 times - 10 times greater than example above).

$ perl mdo_perf1
Run Time data1 = 42.5552821159363
Run Time data2 = 203.071125030518

Scott
- ---
Scott Penrose
Digital Dimensions
scott at dd.com.au
http://www.dd.com.au/













- -- 
Scott Penrose
VP in charge of Pancakes
http://linux.dd.com.au/
scottp at dd.com.au

Dismaimer: If you receive this email in error - please eat it  
immediately to prevent it from falling into the wrong hands.

Please do not send me Word or PowerPoint attachments.
See http://www.fsf.org/philosophy/no-word-attachments.html 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (Darwin)

iD8DBQFAi6bpDCFCcmAm26YRAjNUAJsHfkVwcLEAGj0nFG3axsIQb89FoQCeN/SC
kclY7y34Jd2kymXpZUKgp34=
=A2Yw
-----END PGP SIGNATURE-----




More information about the Melbourne-pm mailing list