lua-users home
lua-l archive

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


Hi, people

I have created a quite large framework for business applications in Lua, and we are now addressing the stress tests in order to improve the performance.

Since I have created a lot of somewhat sophisticated tables to represent fields in a Business Entity, I am having a little problem duplicating some of those fields in instantiation. My field is a table full of functions and attributes, and I have to copy a lot of things from the 'fieldClass' table to a new 'fieldInstance' table to create every field in an Entity - and that´s quite expensive.

I am begining to redesign it now (thinking of using metatables), and I would like to know if there is any proven idiom for this kind of stuff in lua.

Here´s what I am thinking:

I´ll separate the field class table in two inner tables: one for attributes and one for methods. The attributes one I will copy (no help there). The methods one I will replace in the instance with a metatable that redirects to the class table' methods table whenever a method is called.

The code will look like this:

local fieldClass = {
    ['#methods'] = {
        get = function(Self)
            return Self.value
        end,
       
        set = function(Self,value)
            Self.value = value
        end,
       
        teste = function( Self, x, y )
            return Self.msg .. tostring(x) .. tostring(y)
        end,
       
        -- some methods to fill some slack
        a = function() print('') end,
        b = function() print('') end,
        c = function() print('') end,
        d = function() print('') end,
        e = function() print('') end,
        f = function() print('') end,
        g = function() print('') end,
        h = function() print('') end,
        i = function() print('') end,
        j = function() print('') end,
    },
   
    -- attributes must stay flat
    value = '',
    type = '',
    form = '',
    mask = '',
    height = '',
    weight = '',
    food = '',
    color = '',
    bla = '',
    blabla = '',
    msg = 'New Message'
   
}


-- metatable to locate methods
__defaultFieldMetaTable = {
    __index =  function(tabela, nome)

        if(not rawget(tabela, nome)) then
                if(not  rawget( rawget(tabela, '#methods'), nome ) ) then
                    return nil;
                else
                    local methodTable = rawget(tabela, '#methods')
                    local theMethod = rawget(methodTable, nome)
                   
                    return function(...)
                        return theMethod(tabela, ...)
                    end
                end
        else
            return rawget(tabela, nome);
        end
    end,
}

setmetatable( fieldClass, __defaultFieldMetaTable )

-- my clone function
clone = function(aTable)
    local newTable = {}
    for _,v in pairs(aTable) do
   
        newTable[_] = aTable[_]
   
    end
    setmetatable( newTable, getmetatable(aTable) )
    return newTable
end

-- measuring time
cloneTime = 0

new = function()
    local newEntity = {}

    for i=0, 50 do
       
        local t = os.clock()
        newEntity['field' .. i] = clone(fieldClass)
        cloneTime = cloneTime + (os.clock() - t)
       
        newEntity['field' .. i].set(i)
    end
   
    return newEntity
end

-- testing...
allEntities = {}

t = os.clock()

for i=0, 4000 do
    table.insert(allEntities, new())
end

print("total: " .. os.clock() - t)
print("clone time: " .. cloneTime)


My problem being: Performance still sucks.
My question: is there anything I could still do in Lua or shall I begin to prepare to move into userdata?

Thanks in advance,

Luís Eduardo Jason Santos