lua-users home
lua-l archive

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


On Thu, Sep 18, 2008 at 12:21 AM, David Manura wrote:
> On another point, I think it's inconsistent that Lua's VM has an
> opcode to obtain the length in bytes of a string (i.e. # s), but
> there's no opcode to obtain the i-th character or byte of a string
> (e.g. s[i]).  This is because a check for string type is hardcoded
> into the "len" event but not the "index" event[1].  Indexing a string
> is a primitive operation on a primitive data type, so isn't that
> worthy of an opcode rather than going through the standard library?
> The presence of such an opcode might significantly improve the speed
> of this and other things, as well as allow string.sub/string.byte
> library functions to be implemented in Lua.

Consider the following patch to lvm.c:luaV_gettable:

--- lua-5.1.4/src/lvm.c 2007-12-28 10:32:23.000000000 -0500
+++ lua-5.1.4-patched/src/lvm.c 2008-09-18 01:02:28.656250000 -0400
@@ -119,6 +119,17 @@
       }
       /* else will try the tag method */
     }
+    else if (ttisstring(t) && ttisnumber(key)) {
+      const int pos = nvalue(key);
+      if (pos < 1 || pos > tsvalue(t)->len) {
+        setnilvalue(val);
+        return;
+      }
+      /* unused: setnvalue(val, getstr(rawtsvalue(t))[pos]); */
+      const char c = getstr(rawtsvalue(t))[pos-1];
+      setsvalue2s(L, val, luaS_newlstr(L, &c, 1));
+      return;
+    }
     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
       luaG_typeerror(L, t, "index");
     if (ttisfunction(tm)) {

Here's a performance test of unpatched Lua v.s. patched Lua on three
styles of indexing strings:

  local s = ("abcdefghijklmnopqrstuvwxyz"):rep(100)
  local sub = string.sub

  for j=1,10000 do
  for i=1,#s do
                             -- unpatched (s)  patched (s)
  --  local c = s:sub(i,i)   --     9.3           9.3
  --  local c = sub(s, i,i)  --     8.7           8.8
  --  local c = s[i]         --     N/A           3.6
  end
  end

So, the the patch reduces the runtime by 60% on this trivial example.
On the more realistic stringinlua.lua, the speed gains are much less
though still measurable (given room for optimization in other areas).