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

I'm rather surprised they didn't optimize that to just iterate the hashtable directly.

You mean inline hv_iternext? The compiler will do that if appropriate. But that's unlikely since hv_iternext is quite big. It would make no sense to put a copy of that code in the function you showed.

How do you figure? It has to allocate the current size + 1.6MB of ram and initialize all of it.

No initialization is needed.

Replies are listed 'Best First'.
Re^13: Why does each() always re-evaluate its argument? ("for_list" )
by NERDVANA (Priest) on Dec 11, 2023 at 07:26 UTC
    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.

      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.