If __newindex and __index metamethods shouldn't be assigned a function, is making an instance wrapper a waste of resources?

Hi,

So I was lurking and saw in a post inside of community tutorials that the __newindex and __index metamethods was expensive and shouldn’t be assigned a function, and caused such a large impact that using it en-masse could lead to visible performance issues.

This is the post, particularly this citation:

when demoing metamethods, you use a function for __index in a usage example of metamethods but […] doing this is incredibly detrimental to performance (as is using __newindex functions)

So my question was is this performance impact so impactful that making an object wrapper taking advantage of using __index and __newindex functions is a waste of resources?

For example, I was planning on making a GuiButton wrapper that allows for fake/scripted button inputs (particularly mouse down and up), and possibly improved control for mouse enter/leave events which would use this __index method which would make calling button methods with a colon pass the button to that method instead of the wrapped object:

buttonController.__index = function(self, index)
	local indexedSelf = rawget(self, index)
	if indexedSelf then
		return indexedSelf
	elseif buttonController[index] then
		return buttonController[index]
	else
		if type(self._button[index]) == 'function' then
			return function(_, ...)
				return self._button[index](self._button, ...)
			end
		else
			return self._button[index]
		end
	end
end

A function will always be less performant than no function so of course when you are comparing no metamethods vs metamethods the latter will be slower. However, I don’t think this “loss” in performance outweighs the immense benefits you get from building efficient and organized systems. This question is subjective though so I would perform benchmarks to see if the cost outweighs the benefits for you and your use case.

1 Like