Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Paraphrase:Is it better to use subroutines or objects?

The questions to ask yourself are:

  1. Do the three subroutines operate on a common piece or set of data?

    If not, there is no point in making your 3 subroutines (class) methods of an uninstantiable class.

  2. If so, is there any benefit to caching the data they process (as instance data)?

    If the data is passed in, processed, returned, then used and/or disposed of, there maybe no point in caching it.

    On the other hand, if the data is accumulate slowly externally, then processed through one sub, retrieved and retained unmodified, and then later passed again to one or more of the subs, it may make sense to accumulate the data into an object instance, call methods on that object instance and only retrieve it once the data has been completely processed.

  3. Will you need to maintain more that one piece or set of data used (separately) by the subs at once?

    A one-instance (at a time) class can be useful, but is less obviously desirable than one where mutliple instances exist at one time.

  4. How much work do the subroutines do when you call them?

    If they only do some small amount of processing each time, but are called many, many times, then any extra overheads involved in using OO rather than subroutines will be magnified.

    If the subs/methods do a reasonably substantial amount of processing at each call, then the (fixed) overheads will becomes insignificant, but if each call does only a small amount of processing, the overhead can become a substantial part of your processing time.

If you decide to go the OO route, then there are several flavours of OO construction possible. Which is appropriate will depend upon the performance of your hardware and the time constraints of your application, along with other more esoteric considerations like 'OO-purity', 'maintainance' and inheritability.

By way of crude demonstration, the following benchmark uses subroutines exported from a module ('subs'), and five flavours of OO, (OO1 .. OO5) with increasing levels of 'OO-ness', to do the same thing. The -N=nn parameter represents the amount of work done within each call, with low numbers being a small amount and larger numbers, more:

P:\test>467452 -N=1 Rate OO5 OO4 OO3 OO2 OO1 subs OO5 18408/s -- -56% -69% -76% -83% -91% OO4 41813/s 127% -- -29% -45% -60% -79% OO3 58681/s 219% 40% -- -23% -44% -71% OO2 76466/s 315% 83% 30% -- -27% -62% OO1 105426/s 473% 152% 80% 38% -- -48% subs 203292/s 1004% 386% 246% 166% 93% -- P:\test>467452 -N=100 Rate OO5 OO4 OO3 OO2 OO1 subs OO5 1886/s -- -7% -27% -29% -68% -69% OO4 2023/s 7% -- -21% -24% -66% -67% OO3 2568/s 36% 27% -- -3% -56% -58% OO2 2652/s 41% 31% 3% -- -55% -57% OO1 5886/s 212% 191% 129% 122% -- -4% subs 6100/s 223% 202% 138% 130% 4% -- P:\test>467452 -N=10000 Rate OO4 OO5 OO2 OO3 OO1 subs OO4 14.5/s -- -1% -26% -27% -68% -69% OO5 14.6/s 1% -- -26% -27% -68% -69% OO2 19.7/s 36% 35% -- -1% -56% -58% OO3 19.9/s 37% 36% 1% -- -56% -57% OO1 45.2/s 211% 209% 129% 127% -- -3% subs 46.8/s 222% 219% 138% 135% 4% -- P:\test>467452 -N=100000 Rate OO4 OO5 OO2 OO3 OO1 subs OO4 1.42/s -- -1% -25% -26% -68% -68% OO5 1.44/s 1% -- -24% -25% -67% -67% OO2 1.89/s 34% 32% -- -1% -57% -57% OO3 1.92/s 36% 34% 2% -- -56% -56% OO1 4.39/s 210% 206% 132% 129% -- -0% subs 4.41/s 212% 207% 133% 130% 0% --

As you can see, subroutines are quicker than even the simplest level of OO, though at the highest levels of work/call, the difference between subs and the simple forms of OO are negligable. And in these cases, the potential maintainance benefits derivable from OO may well be your deciding factor. Whether the OO-purity arguments should be weighted into you considerations will probably depend upon the performance requirements of your application.

You pay's your money and takes your choice.

Benchmark and Module code

#! perl -slw use strict; use Benchmark qw[ cmpthese ]; use Dummy1; use Dummy2; use Dummy3; use Dummy4; use Dummy5; use Dummy6; our $N ||= 100; our @data = 1 .. $N; cmpthese -3, { subs=> q[ my @modified = sumem( reversem( @data ) ); ], OO1 => q[ my $obj = new Dummy2; my @modified = $obj->sumem( $obj->reversem( @data ) ); ], OO2 => q[ my $obj = new Dummy3( @data ); $obj->reversem; my @modified = $obj->sumem; ], OO3 => q[ my $obj = new Dummy4( @data ); $obj->reversem; my @modified = $obj->sumem; ], OO4 => q[ my $obj = new Dummy5( @data ); $obj->reversem; my @modified = $obj->sumem; ], OO5 => q[ my $obj = new Dummy6( @data ); $obj->reversem; my @modified = $obj->sumem; ], };

Dummy1.pm

use strict; package Dummy1; our @ISA = 'Exporter'; our @EXPORT = qw[ sumem reversem ]; sub sumem { my $sum += $_ for @_; return $sum; } sub reversem { return map{ scalar reverse } @_; } 1;

Dummy2.pm

#! perl -slw use strict; package Dummy2; sub new { my $class = shift; return bless [], $class; } sub sumem { my $self = shift; my $sum += $_ for @_; return $sum; } sub reversem { my $self = shift; return map{ scalar reverse } @_; } 1;

Dummy3.pm

#! perl -slw use strict; package Dummy3; sub new { my $class = shift; return bless [ @_ ], $class; } sub sumem { my $self = shift; my $sum += $_ for @{ $self }; return $sum; } sub reversem { my $self = shift; @{ $self } = map{ scalar reverse } @{ $self }; } 1;

Dummy4.pm

#! perl -slw use strict; package Dummy4; sub new { my $class = shift; return bless { data => \@_ }, $class; } sub sumem { my $self = shift; my $sum += $_ for @{ $self->{ data } }; return $sum; } sub reversem { my $self = shift; @{ $self->{ data } } = map{ scalar reverse } @{ $self->{ data } } +; } 1;

Dummy5.pm

#! perl -slw use strict; package Dummy5; sub new { my $class = shift; my $self = bless {}, $class; $self->_setData( @_ ); return $self; } sub _getData { my $self = shift; return @{ $self->{ data } }; } sub _setData { my $self = shift; return @{ $self->{ data } } = @_; } sub sumem { my $self = shift; my $sum += $_ for $self->_getData(); return $sum; } sub reversem { my $self = shift; $self->_setData( map{ scalar reverse } $self->_getData() ); } 1;

Dummy6.pm

#! perl -slw use strict; package Dummy6; my %dummies; sub new { my $class = shift; my $self = bless {}, $class; $dummies{ $self } = {}; $self->_setData( @_ ); return $self; } sub _getData { my $self = $dummies{ +shift }; return @{ $self->{ data } }; } sub _setData { my $self = $dummies{ +shift }; return @{ $self->{ data } } = @_; } sub sumem { my $self = shift; my $sum += $_ for $self->_getData(); return $sum; } sub reversem { my $self = shift; $self->_setData( map{ scalar reverse } $self->_getData() ); } 1;

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

In reply to Re: Making an Object faster? by BrowserUk
in thread Making an Object faster? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-04-24 06:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found