Are methods unefficient?

Let’s suppose I have a module script that manages players’ camera functionalities. I’ve heard on some posts that methods are less efficient than normal functions:

local camera = {}
camera.__index = camera

function camera.New(Character)
    local self = {}
   
    self.Character = Character
    self.Humanoid = Character:WaitForChild("Humanoid")

    return setmetatable(self, camera)
end

function camera:Booble()
    local hum = self.Humanoid

    -- Booble system using Humanoid from self.Humanoid
end

return camera
local camera = {}

function camera.Booble(Humanoid) -- Or store Humanoid in the module script as a variable
    -- Booble system using Humanoid from the parameter
end

return camera

Are methods really bad? And if it is, when should I refrain from using them? Regarding the first example script I sent, is it necessary to store Character into an OOP to use it further in the script, or use the second example script?

1 Like

manually calling everything will be better obviously but you will only get benefits if you are storing function dirrectly:

local Clone = game.Clone

Also i probably should legit make copy paste explaining people how modules work
Dawg bro ts pmo :wilted_flower:

1 Like

Regarding OOP, there will always be performance trade-offs. OOP is known for not being… well optimised, but it’s very helpful.

In terms of a method, there will be a fair bit of overhead; Luau first searches the table, then gets the metatable, sees if __index is set, sees it is, and then searches that table, finds the key, and returns it.

Having a normal function will induce less overhead because the function has known placement, and doesn’t need to be searched for as much. So Luau just grabs it, and off it goes.

In both parts, parameters will induce the same amount of overhead, because they get pushed to the stack with the function.

Manually storing a function, like @Yarik_superpro said, will be faster overall because Luau does not search for the function when it is called, each time it is called, rather it is searched for at the start and referenced by an upvalue, inducing less overhead.

Overall, OOP methods will be less efficient because of the additional search and call overhead.

3 Likes

Since you’re storing both functions in a dictionary, the real performance difference here would be invoking the __index metamethod.

If you want max efficiency (which may be preferable in the case you’re calling these methods every frame), you should store these functions as locals.

local function Bobble(Humanoid)
end

return Bobble
local Bobble = require(script.Camer)

This keeps the functions in VM registers, which are much more faster to access than dictionaries.

Other than performance, OOP is designed to manage a class structure, which makes it easier to control multiple objects that essentially have the same functions and behaviors, such as guns, cars, or even pets. Therefore, there is no benefits in using OOP for a single object such as the camera.

1 Like

Expanding on this; why are you creating a class for something such as your camera? If you’re planning to instantiate it as a singleton, there’s only a point in doing that if you have extra data and methods you need to be centralised and shared which cannot be shared by other means. Is this the case?

If not, consider a normal module, as you can provide centralised functions without as much index overhead or a wrapper.

2 Likes

I have been wondering that too.
I suppose this issue comes with education building the wrong mindset in beginners or it being their attempts to fill gaps in knowledge.
That’s the same thing as when they are using “Init” or such a method in class creation instead of it being integrated into the constructor.
That being the main reason why I feel disgusted to use OOP in general.

3 Likes

I don’t think it’s an education issue, but rather an attempt to ‘flex’ their scripting skills by overcomplicating scripts and believing it makes them look more professional. Many scripters aspire to learn and use OOP because it is primarily used by highly experienced developers, then think that using OOP mean your’re a good scripter. So once they learn it, they tend to use it everywhere, even when it might not be necessary.

1 Like

I have seen in my ads a lot of “OOP” slop courses pop up, and I think it’s the main source of disease. People are taught that OOP is so perfect and such that they get completely zombified into using it everywhere, even in stupid nonsense cases.
Does anyone remember the knit epidemic?

3 Likes

So, if I am doing a module script with several functions, example:

local _M = {}

function _M.Print()

end

function _M.DoSomething()

end

function _M.DoAnotherThing()

end

function _M.Whatever()

end

return _M

It’s advised that I store them all in a script I want to use them? And should I not use methods at any cost?

If you don’t get what I mean:

local module = require(path._M)

local print = module.Print
local doSomething = module.DoSomething
local doAnotherThing = module.DoAnotherThing
local whatever = module.Whatever

No.

OOP is not always bad. Although it has a costly performance trade-off, it’s a lifesaver for organising complex systems, hence why some languages literally have it built in.

A simple module like _M - I wouldn’t worry about storing it separately, it’s not actually that much overhead for something like that.

OOP - the same, but more overhead. It’s kind of down to microoptimisations at this point.

If you want a golden rule to follow:
Don’t try to use OOP for the sake of it. Only use it where you actually need it.

2 Likes

if you want a little abstraction i guess you can but dunno man.
you can make it even more dead simple:

return {
_M.Print=function()

end;
_M.DoSomething=function()

end
}

Methods and OOP is fine if its not abused the hell out of it and if its well optimized. (i mean why do you need OOP without methods in first place? just referance function dirrectly)
Also make sure to inline functions from module:

local module = require("./MyModule")
local Print,DoSomething = module.Print,DoSomething
--althrough probably avoid this tuple type like referancing probably



you can also implement most of OOP with functional programming instead and it may even be way easier to use…
Singletons in OOP is a joke, just use dirrect functions

I have a module script that handles items that appear on my game. For example, if I want to create a new item, I call for New function to create a new Item object, and then I can do whatever I want with it:

local item = Module.New("Apple", {Health = 30}) -- Example

local name = item:GetName() -- Returns the item's name, in this case "Apple"
local spawn = item:SetSpawn(position) -- Sets the item spawn
local spawnTime = item:SetSpawnTime(60) -- Will appear after 60 seconds

item:StartCountdown() -- Will yield the current thread until item appear with the specified spawnTime

item:Spawn() -- Will spawn the item with the position specified

Is it a good OOP practice, in this case? Or should I refrain to use it still? Because if I didn’t do an OOP for this type of thing, I would probably need to do a lot of functions with parameters and would just look ugly in my opinion.

can’t you just do something like

local item = Module.New("Apple",{Health=30})

local name = item.name -- or item.Name
1 Like

If you plan to have multiple, then yes. But like @1kaelen1 said, try to use properties - they’ll create less overhead than extra functions to read other data.

Otherwise, don’t.

1 Like

Don’t overprotect code from yourself :skull:

Is absolutelly right!
Just index it dirrectly
Roblox sandboxed everything BUT YOU DONT HAVE TO!

1 Like

Alright. Thanks everyone ^^

This text will be not blurred

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.