lua-users home
lua-l archive

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


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello. I have 4 different approaches for creating a classical
OOP-style class in Lua. I'm wondering how they compare in terms of CPU
and memory usage.


#### Approach 1: Metatables ####
This is the standard approach.


local Player = {}
Player.__index = Player

Player.new = function(self, x, y, w, h)
	return setmetatable({x = x, y = y, w = w, h = h}, Player)
end

Player.step = function(self)
	...
end

Player.draw = function(self)
	...
end


#### Approach 2: No metatables ####
Each instance has references to all methods. No metatables are used.


local Player = {}

Player.new = function(self, x, y, w, h)
	local instance = {x = x, y = y, w = w, h = h}
	instance.step = Player.step
	instance.draw = Player.draw
	return instance
end

Player.step = function(self)
	...
end

Player.draw = function(self)
	...
end


#### Approach 3: No metatables, with closures ####
Just like "approach 2", but with in-lined functions. This is prettier.
But Does it use more memory when many instances are created?


local Player = {}

Player.new = function(self, x, y, w, h)
	local instance = {x = x, y = y, w = w, h = h}
	instance.step = function(self)
		...
	end

	instance.draw = function(self)
		...
	end
	return instance
end


#### Approach 4: Metatables with a twist ####
Each instance only has references to the methods it uses. I'm not sure
if this has an official name or if it's widely used. I came up with it
by arbitrarily assuming that metatables are expensive. This approach
accesses the metatable only when a method is called for the first time
for an instance. On subsequent method calls, the method would be
accessed directly without resorting to metatables.


local Player = {}
Player.__index = function(table, key)
table[key] = Player[key]
return Player[key]
end

Player.new = function(self, x, y, w, h)
	return setmetatable({x = x, y = y, w = w, h = h}, Player)
end

Player.step = function(self)
...
end

Player.draw = function(self)
...
end


How do the 4 approaches compare in terms of CPU and memory usage?
Below is my own reasoning. But since I'm inexperienced with Lua, I may
be incorrect.

- - Approach 1: The best in terms of memory. Because instances don't
have to store extra references for each method.

- - Approach 2: Under the assumption that metatables are slower than
direct access, this would be faster than "approach 1". But it would be
more memory-hungry because of the extra references.

- - Approach 3: Do reference to the same closure internally point to the
same code? If yes, this is pretty much like "approach 2". If not, this
is more memory hungry.

- - Approach 4: A better version of approach 2, because memory is
allocated lazily, and instances don't keep references to methods
they've never used.



- - How accurate is my analysis?
- - which approaches are better under what conditions?
- - How do the methods compare in terms of CPU and memory?
- - Is my assumption in "Approach 2" correct? (metatables are slower
than direct access). If so, is the speed difference significant?
- - Is my assumption in "Approach 4" correct? (Creating the same closure
X times uses more memory than creating 1 function and referencing it X
times)
- - Is method 4 commonly used?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWbu4+AAoJENivoBfRYOGKD7wP/3k+BvgSyvIh0Cd+P00yRlH8
RcNa2x3+mJzdII0aVUjib+GfNdLOirNee380rZYZFinrbMb1w4Z0/hTUh3QiX1Cj
5EMbbE0MfzOnTHPfTXehC5z8tyeld+9zCMcsyCfjl3Rx4bv247ik37BwgkEf/WVg
oGDUkLPZ5kUTrscKAF3I8D3hw3CfKxw/7ewmqjBkyanT9edcU45UiE+pjnDcS8nM
Vktaex3T0KfOkIVucg1nYsSHkPJYNPN7ZvtnaUhibU5Xd3z+SO0PWmrBI3bfQnI1
jgJUCpDZkgj+9skBCbJloSaFb+8fzwbfSpJn/MQH7QTdIx0xw7UTLwqAN/QmTTi3
QkSimlvg6oOBJVsKBLl2Q0hlbtwxnrJVH9vpLfgO0q+jfhF+BJrI8WIJm2U4syxf
Lyvqr3CWl3Im6NPDSTxD97h60TfsoAmKlV5RAdY5MbGmJhh506zh+pke0Bfi4fLO
FAtFlrOTX+YzuoSOVKXCbrpVTp2sZHqQVvLWlu3CY5qJm4Ocgm5hio/AdlPg6+gU
e93ckpdC2pjshgDaCB2aATccNYJqQQaR/kiul6JDQSvxs9c9kkMs8OWV91GHyPeG
KGqtkPNO1z1XpTBCEfBi2YqYgsQ/3av0X53h5JiB+pgtahYag3gXLkhFyHAC+QEB
+ZJEbFBMPFbxv0GusKOj
=FrED
-----END PGP SIGNATURE-----

Attachment: 0xD160E18A.asc
Description: application/pgp-keys