Raffaele Salmaso wrote:
[snip]
Ok, final draft. I think it is the best version. I improved the speed a
lot, using David's idea. Now I cache the function object directly in
the instance object itself, so the overhead is very minimal, only the
first time. I've also removed the table ~= klass test, which is always
true (thanks Rici).
This is what I get with the last version
16:19:36 Mer Dic 08 raf@ice ~
$ cat klass.lua
...
object = class()
function object.test_loop(self)
return 1
end
...
c=child()
for i=1,10000 do
c.test_loop()
end
16:19:36 Mer Dic 08 raf@ice ~
$ time lua klass.lua
real 0m0.372s
user 0m0.140s
sys 0m0.010s
16:19:42 Mer Dic 08 raf@ice ~
$ time lua klass.lua
real 0m0.266s
user 0m0.130s
sys 0m0.030s
16:19:43 Mer Dic 08 raf@ice ~
$ time lua klass.lua
real 0m0.238s
user 0m0.120s
sys 0m0.030s
And here is what I get with a similar python code
16:24:02 Mer Dic 08 raf@ice ~
$ cat class.py
class object:
def method(self):
return 1
o=object()
for x in xrange(10000):
o.method()
16:24:09 Mer Dic 08 raf@ice ~
$ time python2.4 class.py
real 0m0.309s
user 0m0.130s
sys 0m0.080s
16:24:10 Mer Dic 08 raf@ice ~
$ time python2.4 class.py
real 0m0.296s
user 0m0.090s
sys 0m0.080s
16:24:11 Mer Dic 08 raf@ice ~
$ time python2.4 class.py
real 0m0.295s
user 0m0.130s
sys 0m0.040s
So the results are very similar, if not the same.
Hope it can be useful.
------------------------------------------------------------------------
--
-- 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 ..
-- IMPORTANT: operators are NOT inherited!
function class(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 type(r) == 'function' then
local f = function(...) return r(table, unpack(arg)) end
table[key] = f
return f
else
return r
end
end
return klass
end
-- ######################
-- test the object system
-- ######################
object = class()
object.id = 42
function object.init(self)
self.x = 0
end
function object.test_loop(self)
return 1
end
function object.__tostring(self)
return '' .. self.x
end
function object.print(self)
print(self.x)
end
function object.__add(self, other)
return self.x + other
end
child = class(object)
function child.init(self)
object.init(self)
self.x = 10
end
function child.__tostring(self)
return '' .. self.id .. ' ' .. self.x
end
function child.__add(self, other)
return self.x + other
end
c=child()
c.print()
print(c)
c=c+30
print(c)
for i=1,10000 do
c.test_loop()
end