lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2012/2/4 Adam Strzelecki <ono@java.pl>:
> I did try already to override __gc for my matrix MT and keep released structures in some kind of cache, unfortunately in tight loops dealllocs are called after to whole loop is finished, so the sequence for 'i = 1, 1000000 do res = mat1 * mat2 end' looks more like 1000000 allocs and then 1000000 deallocs, rather than 1000000 interleaved alloc+dealloc. So caching does not really work there.

Calling collectgarbage periodically from your matrix constructor might
help, if that isn't a big no-no for you...
I experimented around with this code a bit, and the concept seems to work:

local ffi = require( "ffi" )

local M = {_NAME = 'Vector3d', _VERSION = '0.0', _DESCRIPTION =
"Module for 3d-math."}
local ctype
local pool = {}
local gCInterval = 2
local noGcCnt = 0
local function addToPool(v)
	pool[#pool+1] = v
end
function M.new(x, y, z)
	if noGcCnt >= gCInterval then
		collectgarbage 'collect'
		noGcCnt = 1
	else
		noGcCnt = noGcCnt + 1
	end
	local v
	if #pool > 0 then
		v = pool[#pool]
		pool[#pool] = nil
		v.x, v.y, v.z = x, y, z
	else
		v = ffi.new(ctype, {x=x, y=y, z=z})
	end
	ffi.gc(v, addToPool)
	return v
end
function M.add(a, b)
	return M.new(a.x + b.x, a.y + b.y, a.z + b.z)
end
ctype = ffi.metatype('struct {double x, y, z;}', {
	__add = M.add,
	__tostring = function(v)
		return ("Vector3d (%s): {%g, %g,
%g}"):format(tostring(ffi.cast('void *', v)), v.x, v.y, v.z)
	end,
})
setmetatable(M, {
	__call = function(_, x, y, z) return M.new(x, y, z) end,
})