John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Writing code like
$$very{nested}{hash}= $something unless exists $$very{nested}{hash};
will the common subexpression for accessing the item be optimized? Deparse doesn't show anything interesting but that's not conclusive. Does anybody know more about this, or can interpret a deeper kind of dump?

—John

Replies are listed 'Best First'.
Re: Are common access expressions optimized?
by Aristotle (Chancellor) on Dec 23, 2002 at 16:07 UTC
    No, it doesn't. Perl's "optimizer" is really pretty dim. The best you can do for exists tests is
    my $very_deep_nested = $very->{deeply}{nested}; $very_deeply_nested->{hash} = $something unless exists $very_deeply_nested->{hash};
    or as I prefer,
    exists $_->{hash} and $_->{hash} = $something for $very->{deeply}{nested};

    Makeshifts last the longest.

      Thanks. I'm looking forward to "given" in Perl 6. I thought about that yesterday when I had a similar temporary that was only needed for the next two lines. Emulating with a one-iteration foreach is probably too obtuse.

        It's what Larry advertises. :) (Look for Topicalization.)

        I don't think it's obtuse at all - you might be surprised the first time you see it, but did you really have any problem reading it? I think it's immediately obvious what is happening.

        Makeshifts last the longest.

      Aristotle,
      Thank you; I now have a better understanding of the word sublime. That's high art. I'm going to go read the LW link in your other reply now.
      --
      Spring: Forces, Coiled Again!
Re: Are common access expressions optimized?
by broquaint (Abbot) on Dec 23, 2002 at 16:13 UTC
    From the looks of this B::Terse output it doesn't look like any optimisation is performed in this case
    HTH

    _________
    broquaint

Re: Are common access expressions optimized?
by Elian (Parson) on Dec 23, 2002 at 17:06 UTC
    To optimize that would involve more code than you might think--once the exist test was done, the code would need to check on the status of $very{nested}, $very{nested}{hash}, and $$very{nested}{hash} as any part of that expression could be tied or otherwise magic. That makes this rather more interesting to optimize.
      Unless the compile-time attributes say that there's nothing funny about it, that even if tied everything leading up to the last deref is "pure" or idempotent.

      I see the opcode structure on the Parrot takes multiple keys directly. Does that help matters?

      So, simply by using a temporary (either named or topicalized), I'm saying explicitly that the subexpression is only to be evaluated once.

      In Perl 6 there is the // or err operator that will take care of some of this, but no native way to handle exists though maybe undef.

        Unless the compile-time attributes say that there's nothing funny about it, that even if tied everything leading up to the last deref is "pure" or idempotent.
        Yep. If you tell us it's OK, we can do it. Whether we will or not is an open question--writing optimzers isn't easy, and it'll likely be a while before parrot gets one anywhere near as good as, say, DEC^WCompaq^WHP's or IBM's C compiler.
        I see the opcode structure on the Parrot takes multiple keys directly. Does that help matters?
        Nah. Makes it even worse. The reason for the multidimensional key structure is so that a tied variable could potentially consume multiple keys at once, as it knows you're looking for a two or three or four level deep thing, so there's even less information (potentially) on how things work. :)