|
Hi, list! Thank you all for your answers. Since there were that many, I would answer them in a single post, sorry. :-) 1. About module() trick (thanks, Javier, I haven't thought about this one). I like to have table population code written by hand -- this gives easy to read 'reference' to available functions in given object. (A poor-mans documentation :-) .) Otherwise your approach seems to be quite good. 2. Why no syntax sugar (var = function(self) vs. function self:var()). I do not like this sugar because I want strong emphasis in my code on that functions are the first-class objects in Lua. It helps when switching from C++ to Lua frequently. (This is nothing more than a personal preference of course.) 3. Why not to clone table. For performance considerations. I want my object creation to be as fast as possible (see benchmark below). 4. Why not metatable approach. I have naively thought that 'plain' table creation would be faster. I wrote a benchmark, and it appears that I was wrong (thank you, Matthew!). I do not quite understand why the difference is so great though. Benchmark is attached. Usage: KBENCH_SCRIPT=factorybench.lua ./kbench.sh *_init is creation of factory function, *_call is call of that function (that is, creation of object -- what I want to optimize). Results: $ time lua factorybench.lua clone_init 10000000 47.66 real 46.99 user 0.20 sys $ time lua factorybench.lua metatable_init 10000000 47.69 real 46.88 user 0.20 sys $ time lua factorybench.lua plain_init 10000000 56.00 real 54.59 user 0.30 sys $ time lua factorybench.lua metatable_call 10000000 5.84 real 5.75 user 0.02 sys $ time lua factorybench.lua plain_call 10000000 18.69 real 18.43 user 0.06 sys $ time lua factorybench.lua clone_call 10000000 66.36 real 64.61 user 0.34 sys Also I do not understand the reasons for significant slowdown of plain_init. Is hash table constructor so heavy? For reference, here is a LuaJIT timings (I see no big differences in relative speeds): $ time luajit -O factorybench.lua clone_init 10000000 37.16 real 36.75 user 0.12 sys $ time luajit -O factorybench.lua metatable_init 10000000 37.18 real 36.69 user 0.13 sys $ time luajit -O factorybench.lua plain_init 10000000 48.67 real 48.00 user 0.18 sys $ time luajit -O factorybench.lua metatable_call 10000000 3.50 real 3.45 user 0.01 sys $ time luajit -O factorybench.lua plain_call 10000000 11.17 real 10.99 user 0.04 sys $ time luajit -O factorybench.lua clone_call 10000000 34.15 real 33.73 user 0.11 sys Alexander. P.S. BTW, I've actually (temporarily) solved my problem by a different way: that class had a large number of copy-pasted getter functions (doh), and I've replaced them with generated functions: local simple_getter do local cache = setmetatable({},{ __index = function(t, k) local v = function(self) return self[k] end rawset(t, k, v) return v end }) simple_getter = function(name) return cache[name] end end local factory do local method1 = function(self) print("method1", tostring(self)) end factory = function() return { method1 = method1; method2 = simple_getter("var1_"); --... methodN = simple_getter("varN_"); -- var1_ = false; varN_ = true; } end end I understand that this does not solve any of performance problems mentioned above -- but for this specific object performance is not issue, and it is kind of first step to refactoring. :-)
Attachment:
kbench.sh
Description: Bourne shell script
Attachment:
factorybench.lua
Description: Binary data