[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Memory usage stats for 5.2 vs 5.3
- From: Tom Sutcliffe <tomsci@...>
- Date: Tue, 13 Jan 2015 17:39:58 +0000
>>
>> It's interesting how much of an effect the TString member had on the
>> usage of lua_newstate in 5.2.3-dummy-TString, I wouldn't have expected
>> that many strings are constructed before luaL_openlibs or similar has
>> been called.
>
> 'luaL_openlibs' creates lots of new strings, with the names of the
> functions being registered.
I meant that lua_newState seemed to be creating a lot of strings, before luaL_openLibs. Thinking about it some more, that'll be for the reserved words in the lexer, and now of course there are a few more of those with the new bitops.
> This new field 'hnext' greatly simplifies the GC of strings (as they can
> live in the 'allgc' list together with all other objects), but we can
> revert to the old design if it proves too expensive.
Taking into account the alignment of a conventional 32-bit CPU (like the ARM), it increases the overhead of TStrings from 16 bytes to 24, which is a quite considerable increase if you have a lot of short strings like variable names. Generally I'm all in favour of simplification (setfenv being replaced by _ENV was supremely elegant and is my go-to example of good language evolution) but the cost in memory here might be a bit too high. In the test case I mentioned where it requires the tetris module, that one change uses over 2% of available RAM before the module has even set up most of its data structures.
Out of interest why does string data need to be strongly aligned? I can't think of a situation offhand where it would ever be needed?
I was wondering if there was an optimisation that could be applied for when Lua strings are constructed from string literals? Since Lua strings are immutable anyway, and C string literals cannot ever mutate or go out of scope (in any implementation I can think of) copying them into RAM seems a bit wasteful. There's even a lua_pushliteral API already isn't there, although it is a simple macro wrapper at present?
Back of an envelope calculation suggests there are about 100 reserved words and variable names in the standard libraries, and if we conservatively assume they are all less than 8 characters long, on 5.2 they use ~2400 bytes and on 5.3 currently ~3200 bytes (assuming no allocator overhead and 8 byte alignment). If we further assume that it wouldn't be that hard to make short strings use a different memory layout, and that we go back to 5.2 string GC, and assume the string data needn't be copied because they're all C literals, you could fit the whole lot in ~1600 bytes. And the more long string literals there are, the better the saving gets.
It might sound a bit excessive just to save a few KB of RAM but when your RAM budget is also measured in KB these are the sort of hoops you start considering :-)
(My even crazier question would be whether it'd be possible to execute precompiled modules in place rather than copying them to RAM in lua_load, but I realise that's a much more complex problem.)
Cheers,
Tom