lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>Oh, if you have made further research on it, could you please 
>expand a bit on 'for key, value in table' ? 
>Is the slowdown for all cases ? Is it merely a consequence of the 
>slowdown of another operation ? 
>I often (read potentially a lot of times per frame) call this, 
>though there are usually only a handful of entries in the table, 
>often just one. Is the slowdown linear with the number of entries, 
>or just an added constant overhead ? 

Benchmark yourself.  I've attached the lvm.c change below (sorry,
non-patch format... just drop in the code).  You should be able to see
the appropriate places.

The speed issue is because Lua 5.0 Alpha calls the function next() for
every entry, and function call overhead is quite a bit (and, of course,
necessary).  Contrast this with Lua 4.1's approach, which is to call a
function only if there was a function specified.

The possibility exists, I suppose, due to the new global tables
approach, that next() could be something different.  For my uses, this
wouldn't be the case, but anyway, benchmark away...

(BTW, I haven't tested the LUA_TFUNCTION part of the new code... only
the LUA_TTABLE... and even for that, I probably am doing something
wrong...)

Josh

-------------------

#if 1
      case OP_TFORLOOP: {
		int type = ttype(ra);
        if (type == LUA_TTABLE) {
		  Table* t = hvalue(ra);
          if ( !luaH_next(L, t, ra + 2) )
		  {
            pc++;  /* skip jump (break loop) */
		  }
          else dojump(pc, GETARG_sBx(*pc) + 1);  /* else jump back */
        }
        else if (type == LUA_TFUNCTION) {
          setobj(ra+4, ra+2);
          setobj(ra+3, ra+1);
          setobj(ra+2, ra);
          L->top = ra+5;
          luaD_call(L, ra+2, GETARG_C(i) + 1);
          L->top = L->ci->top;
          if (ttisnil(RA(i)+2)) pc++;  /* skip jump (break loop) */
          else dojump(pc, GETARG_sBx(*pc) + 1);  /* else jump back */
        }
        else
          luaG_runerror(L, "`for' value must be a table or function");
        break;
      }
#endif 1
#if 0
      case OP_TFORLOOP: {
        setobj(ra+4, ra+2);
        setobj(ra+3, ra+1);
        setobj(ra+2, ra);
        L->top = ra+5;
        luaD_call(L, ra+2, GETARG_C(i) + 1);
        L->top = L->ci->top;
        if (ttisnil(RA(i)+2)) pc++;  /* skip jump (break loop) */
        else dojump(pc, GETARG_sBx(*pc) + 1);  /* else jump back */
        break;
      }
#endif 0
      case OP_TFORPREP: {  /* for compatibility only */
#if 0
        if (ttistable(ra)) {
          setobj(ra+1, ra);
          setobj(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
        }
#endif 0
        dojump(pc, GETARG_sBx(i));
        break;
      }