Re: Function to force table to shrink?

'Lars Müller' via lua-l <[email protected]>
Newsgroups gmane.comp.lang.lua.general
Message-ID <[email protected]>
Thanks for the reply Roberto!

That was the premise of my "allow rehash" snippet: To add a new key 
leading to a rehash, and to then immediately remove it after.

However, on the latest version of PUC-Lua (commit 
c6b484823806e08e1756b1a6066a3ace6f080fae), I have so far been unable to 
get tables to shrink at all.

When I run your example, it prints roughly the same number 3 times.

Whereas on 5.4, it works as expected, printing a much smaller number 
the third time.

This is consistent with what I see when I run my own testing script 
(<http://vps.luatic.dev/dump/shrink.lua>), which also tries a few more 
things.

Still neither PUC-Lua 5.4 or LuaJIT can be made to reliably shrink 
tables either, even if they're used only as "lists", it seems.

The "add a key to the hash part" trick shrinks only a single time. 
After that, you have a hash part capacity of 1, so the next time you 
try it, it won't work. You'd need to add two keys. Then four keys the 
time after that. And so on. And while doing this, you're also 
increasing the garbage hash part capacity unnecessarily...

This means I can get the array part to shrink (depending on the 
interpreter) by triggering a hash part rehash, but that seems to be 
about the only way, and for the above reason, can't be repeated well, 
so it's not really a solid option.

The hash part meanwhile seems impossible to shrink - unless part of it 
is migrated to the array part - but then we can't drop the garbage 
array part.

Now, what could PUC-Lua do?

It seems that you can get away surprisingly well with not shrinking, 
but I think then this should be mentioned in the reference manual, as 
programmers need to be aware that they should replace the table itself 
if possible, if many entries have been dropped. Currently an 
unsuspecting programmer might very well expect that containers shrink, 
especially as Lua is garbage collected. Indeed, this might present 
itself like a memory leak in some pathological situations: The memory 
usage of Lua is not proportional to the size of the live data 
structures.
As a consequence, iterating a table need not take time proportional to 
the number of entries.

There are ways to ensure a linear relationship between the number of 
entries of a table and its capacity,
but all of them are probably neither cheap (in terms of runtime and/or 
additional memory usage), nor are they particularly simple.
One problem here is that entry deletion not invalidating iterators 
complicates shrinking because it would lose the order.
Either this restriction could be removed, or shrinking could only run 
once it has been explicitly permitted by insertion of a new key-value 
pair.

In the meantime, I think Lua users - at least those that carefully read 
the reference manual - should be made aware of this limitation, and 
perhaps even be given a "table.shrink(t)" or similar that lets them 
explicitly get rid of unused capacity in a table.

- Lars

On Mon, Feb 2 2026 at 16:04:58 -03:00:00, Roberto Ierusalimschy 
<[email protected]> wrote:
>>  I was under the impression that PUC Lua does actually shrink tables
>>  sometimes, at least the hash part, but I will check the sources and 
>> test
>>  again (unless the authors would like to answer off the top of their 
>> heads
>>  ;)) so I can make some reasonable statements about what is likely 
>> to happen
>>  and when.
> 
> A table will shrink if you keep adding keys to it. Adding keys will
> eventually force a rehash; if, at that point, the table needs less 
> space
> than it was using, it shrinks.
> 
> ------------------------------------------------
> local a = {}
> 
> for i = 1, 1e5 do a[i] = true end
> print(collectgarbage"count" * 1024)
> 
> for i = 1, 1e5 do a[i] = nil end
> print(collectgarbage"count" * 1024)
> 
> a.x = true
> print(collectgarbage"count" * 1024)
> ------------------------------------------------
> 
> -- Roberto
> 
> --
> You received this message because you are subscribed to the Google 
> Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, 
> send an email to [email protected] 
> <mailto:[email protected]>.
> To view this discussion visit 
> <https://groups.google.com/d/msgid/lua-l/20260202190458.GB10552%40arraial.inf.puc-rio.br>.

-- 
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/lua-l/6C6W9T.NLVZWW0B5TS42%40gmx.de.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.