I wrote a benchmark to compare tied scalar with get-and-set processing, and with mutation (passing a code ref to apply to the variable). Results are somewhat disappointing, though not necessarily prohibitive:
Rate tie mutate mutate2 getnset naked tie 77.4/s -- -27% -36% -54% -93% mutate 107/s 38% -- -11% -37% -91% mutate2 120/s 55% 13% -- -29% -90% getnset 169/s 118% 58% 40% -- -86% naked 1181/s 1426% 1007% 882% 601% --
naked
is direct access to the variable. This is included for a performance upper bound.
getnset
is a classic two-method-call way of modifying the member
mutate
is a one-method-call way to get, set, or modify (via code ref) the member
mutate2
uses only the get and set forms of the mutate method (to illustrate the overhead of simply having the extra test)
tie
uses a tied scalar whose STORE and FETCH are essentially identical to the get and set methods
The overhead for simply having the encapsulation (the difference between naked and getnset) is about a factor of 6. The overhead for using tie adds another factor of 2+. The more complex the behind-the-scenes machinations of storing and fetching, the less important that overhead will be, but it is significant.

One note about my benchmark program: if you pass it a non-zero argument, it will pass that on to cmpthese. If you don't, it will just sample-run each method to verify that the output is sensible. Use a negative arg for seconds, as positive one for iterations.

#! perl use strict; package Ring; use Carp; sub TIESCALAR { my $class = shift; my $arg; bless \$arg, $class; } sub FETCH { my $self = shift; confess "wrong type" unless ref $self; croak "usage error" if @_; return $$self; } sub STORE { my $self = shift; confess "wrong type" unless ref $self; my $newval = shift; croak "usage error" if @_; $$self = $newval % 12; } package MyOb; use Carp; sub new { my $class = shift; my $struct = { tie => 0, getnset => 0, mutate => 0, naked => 0 }; tie $struct->{'tie'}, 'Ring'; bless $struct, $class; } sub get { my $self = shift; confess "wrong type" unless ref $self; croak "usage error" if @_; return $self->{'getnset'}; } sub set { my $self = shift; confess "wrong type" unless ref $self; my $newval = shift; croak "usage error" if @_; $self->{'getnset'} = $newval % 12; } use UNIVERSAL 'isa'; sub mutate { my $self = shift; confess "wrong type" unless ref $self; if (@_) { my $set = shift; if (isa($set, 'CODE')) { $set->() for $self->{'mutate'}; } else { $self->{'mutate'} = $set } $self->{'mutate'} %= 12; } $self->{'mutate'}; } package Main; use Benchmark ':all'; my $arg = shift; my $ob = MyOb->new; if ($arg) { cmpthese($arg, { 'naked' => sub { $ob->{'naked'}++, $ob->{'naked'} %= 12 for 1..1 +00 }, 'tie' => sub { ++$ob->{'tie'} for 1..100 }, 'mutate' => sub { $ob->mutate(sub{++$_}) for 1..100 }, 'getnset' => sub { $ob->set($ob->get + 1) for 1..100 }, 'mutate2' => sub { $ob->mutate($ob->mutate + 1) for 1..100 }, }); } else { print 'Naked: '; &{sub { $ob->{'naked'}++, $ob->{'naked'} %= 12 for 1..100 }}; print $ob->{'naked'},"\n"; print 'Tie: '; &{sub { ++$ob->{'tie'} for 1..100 }}; print $ob->{'tie'}, "\n"; print 'Mutate: '; &{sub { $ob->mutate(sub{++$_}) for 1..100 }}; print $ob->mutate, "\n"; print 'GetNSet: '; &{sub { $ob->set($ob->get + 1) for 1..100 }}; print $ob->get, "\n"; $ob->mutate(0); print 'Mutate: '; &{sub { $ob->mutate($ob->mutate + 1) for 1..100 }}; print $ob->mutate, "\n"; }

We're not really tightening our belts, it just feels that way because we're getting fatter.

In reply to Benchmark: Encapsulation without methods by Roy Johnson
in thread Encapsulation without methods by Roy Johnson

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.