[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Object system
- From: Raffaele Salmaso <raffaele@...>
- Date: Tue, 07 Dec 2004 10:45:12 +0100
David Given wrote:
Incidentally, it occurs to me that you should be able to optimise things by
making __call pregenerate all the closures. It ought to be something along the
lines of:
__call = function(self, ...)
tmp = {}
setmetatable(tmp, klass)
for i, j in pairs(super) do
tmp[i] = function (...)
return j(tmp, unpack(arg))
end
end
if self.init then
self.init(tmp, unpack(arg))
end
return tmp
end
...although that doesn't take in to account object inheritence.
Would that work? If so, would it speed things up any?
I don't think it would works. It would works only for one level of
inheritance.
I've modified the class() function to add a cache for the methods, and
tested on my machine (apple ibook G3 800 640Mb) with lua 5.0.2
without cache
10:32:47 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.877s
user 0m1.420s
sys 0m0.040s
10:33:57 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.912s
user 0m1.450s
sys 0m0.040s
10:34:00 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.924s
user 0m1.480s
sys 0m0.040s
with cache
10:34:03 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.377s
user 0m1.030s
sys 0m0.050s
10:34:46 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.453s
user 0m1.060s
sys 0m0.030s
10:34:48 Mar Dic 07 raf@ice ~
$ time lua klass.lua
real 0m1.431s
user 0m1.070s
sys 0m0.030s
So with a cache is really faster. But you trade speed with (memory) space.
Attacched are the two version, bugs free (I hope!), and a little test.
--
()_() | Always keep the Titanic in mind when I talk | +----
(o.o) | about security or safety, meaning that nothin | +---+
'm m' | is fully secure. | O |
(___) | raffaele punto salmaso presso libero punto it
GPG fingerprint 1CF5 51D4 E528 EB87 9977 B277 BE8C BF1E 620C 40ED
--
-- Copyright (C) 2004, Salmaso Raffaele <raffaele@salmaso.org>
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
-- 3. If the binary program depends on a modified version of this package,
-- you are encouraged to publicly release the modified version of this
-- package.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
-- operator overloading
-- __add +
-- __mul *
-- __sub -
-- __div /
-- __le <=
-- __lt <
-- __eq ==
-- __tostring
-- __call ()
-- __index []
-- __newindex
-- __pow ^
-- __unm
-- __concat ..
function class_nocache(super)
-- create a new class description
local klass = {}
-- set the superclass (for object inheritance)
setmetatable(klass, {
__index = super,
__call = function(self, ...)
local tmp = {}
setmetatable(tmp, klass)
if self.init then
self.init(tmp, unpack(arg))
end
return tmp
end
})
klass.__index = function(table, key)
local r = klass[key]
if table ~= klass and type(r) == 'function' then
return function(...) return r(table, unpack(arg)) end
else
return r
end
end
return klass
end
function class_cache(super)
-- create a new class description
local klass = {}
-- set the superclass (for object inheritance)
setmetatable(klass, {
__index = super,
__call = function(self, ...)
local tmp = {}
setmetatable(tmp, klass)
tmp.__method_cache__ = {}
if self.init then
self.init(tmp, unpack(arg))
end
return tmp
end
})
klass.__index = function(table, key)
local r = klass[key]
if table ~= klass and type(r) == 'function' then
local f = table.__method_cache__[r]
if not f then
f = function(...) return r(table, unpack(arg)) end
table.__method_cache__[r] = f
end
return f
else
return r
end
end
return klass
end
class = class_nocache
-- ######################
-- test the object system
-- ######################
object = class()
function object.method(self)
return 1
end
o=object()
for i=1,100000 do
o.method()
end