Skip to content

Instantly share code, notes, and snippets.

@gphg
Last active January 21, 2025 20:06
Show Gist options
  • Save gphg/d532d6a9410287e2025f13deab872655 to your computer and use it in GitHub Desktop.
Save gphg/d532d6a9410287e2025f13deab872655 to your computer and use it in GitHub Desktop.
-- https://github.com/openresty/lua-tablepool
-- With slightly modifications.
local newtab = require "table.new"
local cleartab = require "table.clear"
local setmetatable = setmetatable
local _M = newtab(0, 2)
local max_pool_size = 200
local pools = newtab(0, 4)
-- cached pool size by hashing in weak reference
local len_cached = newtab(0, 4)
setmetatable(len_cached, { __mode = 'k' })
function _M.fetch(tag, narr, nrec)
local pool = pools[tag]
if not pool then
pool = newtab(4, 0)
pools[tag] = pool
len_cached[pool] = 0
else
local len = len_cached[pool] or 0
if len > 0 then
local obj = pool[len]
pool[len] = nil
len_cached[pool] = len - 1
-- ngx.log(ngx.ERR, "HIT")
return obj
end
end
return newtab(narr, nrec)
end
function _M.release(tag, obj, noclear)
if not obj then
error("object empty", 2)
end
local pool = pools[tag]
if not pool then
pool = newtab(4, 0)
pools[tag] = pool
len_cached[pool] = 0
end
do
local cnt = (len_cached[pool] or 0) + 1
if cnt >= 20000 then
pool = newtab(4, 0)
pools[tag] = pool
len_cached[pool] = 0
return
end
len_cached[pool] = cnt
end
local len = (len_cached[pool] or 0) + 1
if len > max_pool_size then
-- discard it simply
return
end
if not noclear then
setmetatable(obj, nil)
cleartab(obj)
end
pool[len] = obj
len_cached[pool] = len
end
return _M
-- vi: ft=lua ts=4 sw=4 et
@gphg
Copy link
Author

gphg commented Jan 21, 2025

table.clear is powerful and destructive.

table.clear(tab) clears a table
An extra library function table.clear() can be made available via require("table.clear"). This clears all keys and values from a table, but preserves the allocated array/hash sizes. This is useful when a table, which is linked from multiple places, needs to be cleared and/or when recycling a table for use by the same context. This avoids managing backlinks, saves an allocation and the overhead of incremental array/hash part growth.

Please note, this function is meant for very specific situations. In most cases it's better to replace the (usually single) link with a new table and let the GC do its work.

If it means for clearing an array, simply just zero them out or nil. Or simply discard it.

table.new is useful on most cases, and also can be poly-fied

It is a lower level table allocation and exclusively for LuaJIT. On specific case, this works the same and archived similar performance:

-- similar to table.new(4, 0), but with pre-declared values: 0
local t = { 0, 0, 0, 0 }

-- note: although this looks the same, but the memory allocation is undetermined 
-- https://gitspartv.github.io/LuaJIT-Benchmarks/#test13
local t = {}
t[1], t[2], t[3], t[4] = 0, 0, 0, 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment