[I'll take off my black hat for a moment...]

Okay, this is the FIRST TIME I've ever seen indirect object syntax
used for anything useful.  (That's praise, BTW)

I was going to suggest that KEYS and VALUES methods be added to tied
hashes, but this RFC makes it all moot.  Well done.

[Black hat back on.]


On Fri, Sep 08, 2000 at 04:57:46AM -0000, Perl6 RFC Librarian wrote:
>    3. It is slow (at least slower than other objects)

Its not slow.  ITS SLOWER THAN MOLASSES ON A COLD DAY ON PLUTO!

Simple benchmarking shows that tied access is nearly an order of
magnitude slower than method access which is nearly an order of
magnitude slower than normal hashes.

    #!/usr/bin/perl -w
    
    use Benchmark;
    
    use Tie::Hash;
    
    tie %tied, 'Tie::StdHash';
    $tied{foo} = 'bar';
    $hash{foo} = 'bar';
    $obj = tied %tied;
    
    timethese(shift || -3, {
                      tied   => sub { $tied{foo} },
                      hash   => sub { $hash{foo} },
                      method => sub { $obj->FETCH('foo') },
                      });
    
Benchmark: timing 200000 iterations of hash, method, tied...
      hash:  1 wallclock secs ( 0.15 usr + -0.01 sys =  0.14 CPU) @ 1428571.43/s 
(n=200000)
            (warning: too few iterations for a reliable count)
    method:  0 wallclock secs ( 0.81 usr +  0.00 sys =  0.81 CPU) @ 246913.58/s 
(n=200000)
      tied:  5 wallclock secs ( 5.00 usr +  0.02 sys =  5.02 CPU) @ 39840.64/s 
(n=200000)


While the disparity between normal hashes and methods is acceptable
(optimized C code vs Perl) that between tied variables and methods is
not.

Anyhow, this horse is long dead.


> =head3 Merge C<TIESCALAR>, C<TIEHASH>, and C<TIEARRAY> into C<TIE>
> 
> In practice, people rarely make a class that C<tie>s multiple data types
> through the same interface. The reason is that C<STORE>, C<FETCH>,
> C<DESTROY>, and other methods overlap. As such, it is more feasible to
> create several different modules; witness C<Tie::Array>, C<Tie::Scalar>,
> C<Apache::Session>, and other modules.

I like this, but I can foresee a problem.

If someone does:

    tie Some::Class $foo;

but Some::Class is really for hashes, you won't know it until
something else blows up.

It may make sense to pass a leading argument to TIE which is the type
of variable being tied.

    tie Some::Class $foo, @args;

would produce:

    TIE('SCALAR', 'Some::Class', @args);


BTW  Should C<Some::Class->tie($foo, @args)> work or would it be
Some::Class->TIE($foo, @args)?  Or both?  Or neither?


> =head3 Perform functions through the indirect object syntax
> 
> Currently, C<tie> incurs a fairly substantial overhead (depending on
> your application) because function calls such as this:
> 
>    push @tied_array, $value;
> 
> Must be internally transformed into this:
> 
>    $self->PUSH($value);

True, but I don't believe this is the real reason for the
inefficiencies.  You might want to ask on p5p for a detailed set of
reasons why tying is inefficient.  I think some of it has to do with
oddities in the implementation.

Also...

> Instead, this RFC proposes that C<tie>'s operation become much more
> fundamental, simply translating functions via the existing indirect
> object syntax:
> 
>    tie Transaction %trans;    # indirect object constructor
>    $trans{$var} = $value ;    # $obj->STORE($var, $value);
>    lock $trans{$var};         # $obj->lock($var);

<furthermore...>

> In each of these examples, the variable that is being C<tie>d acts like
> little more than a syntactic mask over an object. Translation is
> potentially much faster because the indirect object syntax is used.

No, a similar translation must be made.

    lock $trans{$var};

must still check to see if %trans is tied.  If so it must retrieve
that tied object and translate to the lock() method call.  Little or
no efficiencies will be had.

(I'm not done yet...)


>    # Include tied interface
>    sub TIE {
>        my $self = self;    # RFC 152 :-)
>        bless {@_}, $self;
>    }

Ya know, this almost points out a weakness in RFC 152.  Why have a
self keyword if you're immediately going to assign it to a variable???
Perhaps it was just from habit.

Anyhow, this is not the place to bring that up as I just did.


> Actually, C<tie> might be able to be handled completely by a
> preprocessor of sorts. Consider this code:
> 
>    tie My::Matrix @a, [ 1, 2, 3 ];
>    @a = @a + @b;           # $obj->CLEAR; $obj->STORE($obj->ADD(@b));
>    @a = @a * @b;           # $obj->CLEAR; $obj->STORE($obj->MUL(@b));
>    push @a, $value;        # $obj->push($value);
> 
> If Perl simply ran something like a C<s/\@a\b\s*,?/\$obj/g> over the
> code internally, then all of this would become:
> 
>    $obj = My::Matrix->tie([1, 2, 3]);
>    $obj = $obj + @b;       # $obj->CLEAR; $obj->STORE($obj->ADD(@b));
>    $obj = $obj * @b;       # $obj->CLEAR; $obj->STORE($obj->MUL(@b));
>    push $obj $value;       # $obj->push($value);

Can't be done.  Consider:

    my $foo;

    if( $something ) {
        tie Some::Class $foo;
    }

    print $foo;

You can't determine at compile time if $foo will be tied or not.
Here's another:

    sub foo {
        my $hash = shift;
        print $hash->{foo};
    }

    my %hash;
    tie Some::Class %hash;
    foo(\%hash);
    foo({foo => "bar"});

Obviously the code of foo() can't be translated.

However, this problem is eerily similar to that of pseudohashes.  You
could make a way of declaring a lexical variable as being tied to a
given class at compile time, similar to the my Dog $spot syntax.... ick.


Again, I think the issue of translation is a red herring.  I believe
the problem to lie elsewhere.  Ask on p5p and try compiling perl5 with
gprof to see where the problem is.





-- 

Michael G Schwern      http://www.pobox.com/~schwern/      [EMAIL PROTECTED]
Just Another Stupid Consultant                      Perl6 Kwalitee Ashuranse
MORONS!

Reply via email to