in reply to Re^12: Why does each() always re-evaluate its argument? ("for_list" )
in thread Why does each() always re-evaluate its argument?

I mean like this recipe that I've seen in various places:
STRLEN max = HvMAX(hv); STRLEN i; for (i = 0; i <= max; i++) { HE *entry = (HvARRAY(hv))[i]; for (; entry; entry = HeNEXT(entry)) {
Of course this can only be used if it isn't magical or tied and so on, but it would be way faster than calling hv_iternext, inlined or not.
  • Comment on Re^13: Why does each() always re-evaluate its argument? ("for_list" )
  • Download Code

Replies are listed 'Best First'.
Re^14: Why does each() always re-evaluate its argument? ("for_list" )
by ikegami (Patriarch) on Dec 11, 2023 at 14:08 UTC

    Of course this can only be used if it isn't magical or tied and so on

    Does it really matter if it's faster if it doesn't work?

      Yes, because you separate the common case (non-magical) from the rare case with an if block, and then use the fast implementation most of the time. I didn't make up that example above, I copied it out of perl's own hv.c, where other various routines have been able to be optimized like that.

      I also understand that there is probably a reason why they didn't optimize this case, but back to my original statement, it surprises me that this code path is using the normal iterator. I would think dumping the elements of a hash would be a frequent enough operation to be worth optimizing.

        Discounting the magic and the code for HV_ITERNEXT_WANTPLACEHOLDERS, that still leaves 20 lines of code.