lua-users home
lua-l archive

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


hmmm, so your storing your tables in the instance, not in the class definition? doesn't that waste a lot of memory?

Couldn't we cache the functions in the class definition instead, then have the instance reference the class definition? Then the definition's cache could still get flushed on reload but you wouldn't have to have a per instance cache.

Paul Du Bois wrote:

You can do it; it just takes a little more effort on the part of your
reload() function. For instance, we don't really construct a c++ vtbl,
but we do cache objects in our instance tables after they've been
looked up from the chain of shared class tables.

Thus, one of the first things we do when reloading class C is to clear
out all cached functions from instance tables. You can tell cached
values by comparing rawget(instancetable, name) to
"normalget"(instancetable.Class, name).

Then we reload the class and let the caching catch up.

p

On Wed, 08 Dec 2004 12:20:31 -0500, John Paquin
<jpaquin@breakawaygames.com> wrote:
with your class system, is it possible to change the lua code (lass.lua
in this case), reload the lua file and expect to see the changes
reflected in existing objects (like c in this case)?  This is a major
downfall of my own class system because I create a table of methods for
each class, much like C++ keeps a single table of virtual methods for
each class.  Then all objects of that class reference this single table.

I think that the only way to incorporate dynamic changes is to
dynamically (i.e. at the time of reference) follow the inheritance chain
backward to find the correct method.

Sorry if this question has already been asked.



Raffaele Salmaso wrote:

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