lua-users home
lua-l archive

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


I have this solution, but the gain was very little. Besides, I have some problems with the : sintax candy for methods - in fact, the meta-table was _intended_ to eliminate it.

I believe the devil in this code is not in the small things.. there´s something very structural about its bad performance, I just can´t put my finger on it... If anything else fails, I´ll try the userdata approach, but that will cost an additional effort I wasn´t expecting.. :-(

Thomas Harning Jr. escreveu:


On 6/11/07, Duncan Cross <duncan.cross@gmail.com> wrote:
>From a quick first glance, you're doing an unnecessary extra table
index (a relatively expensive operation) in your clone function -

>  clone = function(aTable)
>      local newTable = {}
>      for _,v in pairs(aTable) do
>
>          newTable[_] = aTable[_]

...you've already got the value of v, you don't need to index aTable again.

I spent a little time on this example....  here's it w/ some optimizations:

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'
  
}


-- Simplified the system and removed closure generation (instead you want to use object-calling syntax sugar: ex:      object:set(i)   rather than object.set(i)
-- metatable to locate methods
__defaultFieldMetaTable = {
    __index =  function(tabela, nome)
    local val = rawget(tabela, nome)
        if not val then
                local methods = rawget(tabela, '#methods')
                return rawget(methods, nome)
        else
            return val
        end
    end,
}

setmetatable( fieldClass, __defaultFieldMetaTable )

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

-- Used more locals since otherwise many table index access would be wasteful
-- measuring time
local cloneTime = 0
local t = os.clock()
local new = function()
    local newEntity = {}
--NOTE: It might be best to move the os.clock items outside of this loop, not sure of the cost of the call
    for i=0, 50 do
      
        local t = os.clock()
        newEntity['field' .. i] = clone(fieldClass)
        cloneTime = cloneTime + (os.clock() - t)
       -- NOTE: Changed set call from  .set to :set  so that the object is implicitly passed as first arg, saving on closure generation/etc
        newEntity['field' .. i]:set(i)
    end
  
    return newEntity
end

-- testing...
local allEntities = {}

for i=0, 4000 do
    allEntities[#allEntities + 1] = new()
end

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

--
Thomas Harning Jr.

--
Luís Eduardo Jason Santos
Coordenador Técnico
IT Quality Systems
lsantos@itquality.com.br
[21]2242-7959 ramal 49