Last active
January 14, 2016 22:43
-
-
Save cezarguimaraes/2618fe938a11aa7d211f to your computer and use it in GitHub Desktop.
Simple Lua 5.2+ module that enables tables to be reused
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
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