Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Speeding-up OO accessor methods

by mirod (Canon)
on Sep 19, 2000 at 01:03 UTC ( [id://33029]=perlquestion: print w/replies, xml ) Need Help??

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

This is half a question (how can this technique be improved?) and half craft (but with too many comments to fit in the craft mold!)

I thought you might one day need this crude-but-efficient (albeit dangerous) technique to speed-up OO modules without compromising the cleaness of the code.

I usually define accessor methods to every attribute of my objects, even those which are implemented as simple hash fields. Thus I have usually a field and a set_field method for each field. I use those accessor methods even within the module, just in case one day I change the implementation and I move the attribute from a simple field to... something else.

Then in order to get back the speed lost in those method calls, when I install the module I pre-process it and replace the methods by hash access through a simple script:

#!/bin/perl -p # basic substitution # processing the field method is easy s/((\$\w+)->field\b/$1\->\{field\}/g; # the set_field method has an argument, capture it s/s/(\$\w+)->set_field\(([^)]*)\)/$1\->\{field\}= $2/g

The actual code I use is improved to process several fields at once, to allow the object to be an array element (hash element is left as an exercice for the reader), and to perform the replacement only if no other argument is passed to the field method:

#!/bin/perl -p BEGIN { $FIELD="field1|field2|field3"; } s/(\$\w+(?:\[\d\])?)->($FIELD)\b(?!\()/$1\->\{$2\}/g; s/(\$\w+(?:\[\d\])?)->set_($FIELD)\(([^)]*)\)/$1\->\{$2\}= $3/g;

Then I just add a depend item in Makefile.PL;

    'depend' => { 'oo.pm' => "oo.pm.slow\n\tperl speedup oo.pm.slow > oo.pm\n"},

Where oo.pm.slow is the code I edit and maintain while oo.pm is the module that gets installed.

One caveat is that you can't use parenthesis in an argument to the set_field method, although this could be fixed using the latest regexp extensions.

Once that script is written you can also use it to speedup scripts that use the module, with the important drawback that when the implementation changes you will have to re-run the speedup script on all such scripts.

Replies are listed 'Best First'.
Re (tilly) 1: Speeding-up OO accessor methods
by tilly (Archbishop) on Sep 19, 2000 at 01:17 UTC
    You improve it by using a hash and if one day you want it to be something else then you will just tie the hash to an OO implementation.

    To tie it all you need to do is provide a class with the OO interface Perl is looking for, then call tie on the data structure you wish to tie.

    Note that the correct documentation is in perldoc perltie - and this is one area where Perl has improved significantly over releases so looking at your local documentation Really Matters On This One.

      I admit I haven'd done any benchmarking here, but aren't tie-ed variables slower than a simple hash access? The whole point of this hack is to get some speed.</pp>

        The whole point of this hack as I see it is to write a ton of code so in the long run you could switch the implementation from hash access (fast) to something slower but more flexible.

        Being prepared to move to a tied interface later gives you that flexibility without any loss in speed or extra coding and development effort up front. Downstream that extra time will likely matter more anyways.

Re: Speeding-up OO accessor methods
by demerphq (Chancellor) on Feb 22, 2004 at 11:08 UTC

    I think a better idea is to use a tied hash as the basis of your class in testing and development, and an untied hash in production release. This way you bypass the requirement for converting from method syntax to hash syntax using a regex. All attributes of the objects are accessed via hash notation. The tie ensures that the keys and values are legal, etc. Then when you switch out of development/test mode, you disable the tie and get the speed benefit of pure hash accesses. You could even selectively enable the tie as required.

    I believe that Damian Conway wrote Tie::SecureHash with this in mind, with the added benefit of namespace rules to aid in subclassing. But I think it may also be worth hand coding in some cases.


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://33029]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2024-03-19 04:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found