lua-users home
lua-l archive

Re: Copying Lua Tables

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




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.

AltStyle によって変換されたページ (->オリジナル) /