Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Sunday November 19, 2006
02:18 PM

Procedural versus OO performance

[ #31662 ]

While playing around with ant algorithms to solve the traveling salesman problem, I realized that the procedural code I was using would probably be easier to read and maintain if I converted it to object oriented code. My ants turned into snails. Eventually I tried hand-tuned OO, my Class::BuildMethods, and Moose. Of course, ant algorithms are AI and and AI is computationally intensive, so while Perl makes it easy to code AI solutions, their runtime performance leaves much to be desired. The original C code was from AI Application Programming, 2nd Edition, by M. Tim Jones, and it runs much faster than the Perl version, of course.

Here are typical sample runs of the Perl code:

Procedural:
the code took:17 wallclock secs (15.73 usr +  0.07 sys = 15.80 CPU)

OO (blessed arrayref)
the code took:34 wallclock secs (32.65 usr +  0.13 sys = 32.78 CPU)

OO (blessed hashref):
the code took:35 wallclock secs (33.31 usr +  0.12 sys = 33.43 CPU)

BuildMethods:
the code took:44 wallclock secs (41.98 usr +  0.16 sys = 42.14 CPU)

Moose:
the code took:37 wallclock secs (35.26 usr +  0.16 sys = 35.42 CPU

Moose was not appreciably slower than traditional OO methods, though my Moose-fu is lacking. My Class::BuildMethods was the worst, but then, that's the price I pay for my "quick prototype" code.

It was interesting to note that the arrayref and the hashref didn't have an appreciable performance difference, but then, even inside of the classes, I was only reaching directly into the data structure in the getter/setters. Most of this overhead appears to be the method calls.

While do some fairly aggressive hand-tuning of the blessed arrayrefs, but still respecting encapsulation outside of the class, I managed to get the following benchmark:

the code took:29 wallclock secs (27.94 usr +  0.13 sys = 28.07 CPU)

That's still over 50% slower than the procedural version, but it does show that performance benefits can be gained when needed.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Is there a chance you could hit it with Class::Trait on the objects? That'd be running without a method cache.
    • I probably could at some point. Their's at least one part of the code which would lend itself to traits fairly well.

      • You could also try using Moose::Role as well, I would be interested to see how you thought the two (Class::Trait & Moose::Role) compared.

        - Stevan
        • I had already screwed up one part of the Moose code (setting a subtype on an accessor). I need to learn Moose better before moving on to advanced stuff.

          I noticed in the Changelog that there are references to Moose performance improvements. It seemed to be fairly speedy for the stuff that I'm doing. Is it fast enough for general use?

          • Is it fast enough for general use?

            Maybe not quite yet. It is getting there though, the current set of performance enhancements are just simple things I found while doing the larger performance enhancements, which I hope to have ready by the end of the month.

            - Stevan
            • While we're on the subject of Moose, have you thought about adding Dump methods to Moose::Autobox? Using something like Data::Dump::Streamer to dump a code reference could be very handy for debugging.