lua-users home
lua-l archive

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


On Wed, Apr 13, 2011 at 2:39 PM, Francesco Abbate
<francesco.bbt@gmail.com> wrote:
> I don't know if I'm missing something but here the code from Lua 5.1.4 VM:
>
>  luaL_Buffer b;
>  luaL_buffinit(L, &b);
>
>  [...]
>
>        case 's': {
>          size_t l;
>          const char *s = luaL_checklstring(L, arg, &l);
>          if (!strchr(form, '.') && l >= 100) {
>            /* no precision and string is too long to be formatted;
>               keep original string */
>            lua_pushvalue(L, arg);
>            luaL_addvalue(&b);
>            continue;  /* skip the `addsize' at the end */
>          }
>          else {
>            sprintf(buff, form, s);
>            break;
>          }
>        }
>
> for me this means that:
> - a Lua string buffer object is used => fast and efficient

I wouldn't eagerly apply the terms fast or efficient to the luaL
buffer system, at least in this situation.

> - if the string is small the value is just blitted to the buffer with sprintf

The '[' and ']' characters go through calls to luaL_addchar, whereas
the value gets passed through sprintf (which itself is massively
complex) into a buffer on the stack, then strlen+luaL_addlstring to
append that to the auxiliary library buffer. The call to
luaL_addlstring then calls luaL_addchar for each character of the
value. This does byte by byte copying to a buffer on the stack, and
possibly calls to adjuststack, which ends up calling luaV_concat.

> - if the string is big the value is appended with luaB_addvalue => efficient

luaL_addvalue is better than the previous paragraph, as it'll do a
single memcpy to a stack buffer, or a call to adjuststack (which as
mentioned, often ends up calling luaV_concat).

Finally, the call to luaL_pushresult will do lua_pushlstring with
whatever is in its stack buffer, then call lua_concat, which in turn
may call luaV_concat. My feeling is thus that the string.format
approach takes a convoluted route to copying things around stack
buffers and/or possibly several calls to luaV_concat, whereas the
concatenation approach is a single direct call to luaV_concat.