That's why inproposef using Nan tagging for storing small values, including many short strings (this is possible with 64bit double, for strings at least up to 6 bytes, not requiring any dynamic allocation and garbage collection !
Thanks for info ... I will think... but such a function
"string.charat" sounds a bit "very special", as it would not be
described in any Lua doc ... a bit difficult to explain to the user ..
but I will think of it ... very useful info at least - thank you.
I already had thought of using string.byte instead... but then instead
of 'A' / 'a' I would have to use 0x41 and 0x61... this really also
does NOT sound very user friendly in any way...
so for now I would stick somehow to string.sub... but maybe I get some
ingenious idea in next future :).
On Wed, Sep 15, 2021 at 7:07 PM Francisco Olarte <folarte@peoplecall.com> wrote:
>
> On Wed, Sep 15, 2021 at 6:52 PM Flyer31 Test <flyer31@googlemail.com> wrote:
> > Oh, very helpful and impressive info is this, thank you very much ... .
> >
> > (this was my main objection against this string.sub, that extensive
> > use would somehow start many many super-small allocations on the
> > heap... I would not have expected that Lua has some means to avoid
> > this - very ingenious indeed then ... In this case I really could
>
> Check that fact first, at least in 5.4.3 string.sub is:
>
> static int str_sub (lua_State *L) {
> size_t l;
> const char *s = luaL_checklstring(L, 1, &l);
> size_t start = posrelatI(luaL_checkinteger(L, 2), l);
> size_t end = getendpos(L, 3, -1, l);
> if (start <= end)
> lua_pushlstring(L, s + start - 1, (end - start) + 1);
> else lua_pushliteral(L, "");
> return 1;
> }
>
> So it seems content is in fact not shared and this:
>
> Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
> > collectgarbage('stop')
> 0
> > collectgarbage('count')
> 21.3662109375
> > s="0123456789abcdefghijklmnopqrstuvwxyz"
> > for i=1,10 do for j=1,26-i do t=string.sub(s,j,i) end end
> > collectgarbage('count')
> 28.2568359375
> > for i=1,26 do for j=1,27-i do t=string.sub(s,j,i) end end
> > collectgarbage('count')
> 34.75
> > collectgarbage()
> 0
> > collectgarbage('count')
> 23.2294921875
>
> Points to memory being consumed for more than a pointer ( 1st loop
> executes about 250 times generating strings of about 5.5 bytes
> averages, uses 7k, which woould be about 300 bytes/str if content was
> shared )
>
> On your ministring, making your own string.charat is trivial in C, you
> could probably make what you need in about a page ( 66 lines ) of C
> code.
>
> Francisco Olarte.