Skip to content

Instantly share code, notes, and snippets.

@cezarguimaraes
Last active January 14, 2016 22:43
Show Gist options
  • Save cezarguimaraes/2618fe938a11aa7d211f to your computer and use it in GitHub Desktop.
Save cezarguimaraes/2618fe938a11aa7d211f to your computer and use it in GitHub Desktop.
Simple Lua 5.2+ module that enables tables to be reused
--[[
Reasoning:
If your program uses (and stops using) a lot of tables, you will be dealing with the memory allocation and deallocation overhead,
Roberto Ierusalimschy suggests "recycling" tables as a way of optimizing code that uses a lot of them. This small module uses the
__gc metamethod (enabled for tables in version 5.2) to know whenever a table isn't being used anymore and stores it for future use,
avoiding an extra deallocation and future allocation of a new table. If you aren't sure that this module will help your code's
performance, do not use it because it might backfire on your goals. Even then you should customize the table clean up (or not clean
them at all) depending on what your are going to use them for.
Usage:
local tablestorage = require('tablestorage')
-- mt: metatable the new table should have
-- array: if true, it is assumed the new table will only have array elements
local t, mt = tablestorage(mt, array)
-- returns an empty table and its metatable
-- Testing:
local list = {}
while true do
io.write('> ')
local input = io.read()
if input == 'q' or input == 'quit' then
break
elseif input:sub(1, 4) == 'add ' then
local entry = tablestorage()
entry.name = input:sub(5)
table.insert(list, entry)
elseif input:sub(1, 3) == 'rm ' then
local cmp = input:sub(4)
for k, v in ipairs(list) do
if v.name == cmp then
table.remove(list, k)
break
end
end
elseif input:sub(1, 4) == 'list' then
for _, v in ipairs(list) do
print(v.name, v)
end
elseif input:sub(1, 7) == 'collect' then
collectgarbage()
else
print 'Incorrect input'
end
end
-- Output:
> add t1
> add t2
> list
t1 table: 0000000000a39870
t2 table: 0000000000a39e30
> rm t2
> collect
> add t3
> list
t1 table: 0000000000a39870
t3 table: 0000000000a39e30
]]
local storage = {}
return function(mt, array)
mt = mt or {}
local finalizer = mt.__gc
mt.__gc = function(self)
if finalizer then
finalizer(self)
end
local iter = array and ipairs or pairs
for k, _ in iter(self) do
self[k] = nil
end
table.insert(storage, self)
end
return setmetatable(table.remove(storage, #storage) or { }, mt)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment