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.
--
|