Performance-wise, what is better: defining function, then connecting it or connecting it with a then defined function?

Hey!
So my question is pretty much in the title already. My question would be following.
If I did:

local Players = game:GetService("Players")

local function OnJoined(plr)
   print(plr.Name .. " just joined the game!")
end

Players.PlayerAdded:Connect(OnJoined)

Would it be a lot better than

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
    print(plr.Name .. " just joined the game!")
end)

?
I don’t know if this is true but I think the second one would create a new function every times a player joins which would be pretty bad performance-wise. Or does Roblox have some optimization for that that?

Thanks!

1 Like

I mean, they’re both exactly the same, and if there’s any “performance impact” must be really minimium and wouldn’t affect gameplay.

Something I do is… Connect player removing in player added, then disconnecting

1 Like

The real significance of defining a function first rather than using an anonymous function is that you can reuse the function. This is particularly useful when you need to call that function outside of when say, a player joins. You might want to call OnPlayerJoined for players that have already joined before your script started listening to Players.PlayerAdded for instance.

2 Likes

Wouldn’t this

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
    print(plr.Name .. " just joined the game!")
end)

create a new function everytimes someone joins?

I would do Player.PlayerRemoving outside of the PlayerAdded as PlayerRemoving fires for all players meaning the event will fire for players other than the Added Player wasting resources and needing extra code to ensure the Player that is being removed is the Player that was added, overall just not a good idea to define it like that.

^^ They are basically the same thing

1 Like
local function Onjoined(plr)
    --function actions
end

Localizes the function to the thread which means it compiles to the memory and runs faster when referenced. A little tip is if you do this:

local OnJoined = function(plr)
    --function actions
end

Is the same thing here so if you wanted to create a global variable without defining it at begging of the script that can be redefined at any given point and referenced outside of a different part of a script with the same value then the function would already be compiled to the script’s memory and able to be redefined at will in any other part or if you want to make it specific to a certain part of the thread then you do:

local OnJoined = --function

instead of:

OnJoined = --function
1 Like

So basically it’s better practice to do:

local OnJoined

Onjoined = function(plr)
    print(plr.Name.." has joined the game!"
end

As it’s better memory handling and more efficient to use as a plus.

1 Like

It’s better to think of events this way:
The line where you write the event, is just a one-time operation, which connects a function (which can be thought of as a callback) to a certain action.
When the function is called happens in the background, the same annonymous function is called each time the action happens.

If you think about it, this operation is gonna only happen once (unless you’re continuously connecting a new function to an event inside of a while loop). So whether you do the former or the latter, there is gonna be a super tiny difference, that’s made even more insignificant because the operation happens only once. As @Optikk said, choose the former if you’re gonna be reusing the function, and maybe sometimes you find it more readable.

2 Likes

I’m pretty sure that’s the same as doing

local OnJoined = function(plr)
   print(plr.Name .. " has joined the game!")
end

which is the same as

local function OnJoined(plr)
   print(plr.Name .. " has joined the game!")
end

That’s what I’m saying. But if you make

local function OnJoined(plr)
    print(plr.Name .. " has joined the game!")
end

a global function like this:

local OnJoined 
OnJoined = function(plr)
    print(plr.Name .. " has joined the game!")
end

You can just reference the function that already been localized and change it if you really need to.

1 Like

It would not! The function is created exactly once, and PlayerAdded calls that same function every time. A function is a first class object in Lua, it can be passed around much the same as a number or table.

Look at it this way:

local function onPlayerAdded(plr) -- defined once
    print(plr.Name .. " just joined the game!")
end
Players.PlayerAdded:Connect(onPlayerAdded) -- connected once

:Connect does not look at the contents of the onPlayerAdded variable every time. Rather, the contents of that variable are passed to Connect, and that’s all it will know and call.
If you reassign onPlayerAdded later after the connection, then the function that PlayerAdded will do does not change, either.


This code would make a new function every time:

Players.PlayerAdded:Connect(function(plr) -- this function is created once
	return (function() -- create a new function every time...
		print(plr.Name .. " just joined the game!") -- plr can be used here, it is a closure
	end)() -- ... and then just call it without doing anything else with it
end)

That’s a lot harder to write. (No, it’s not universally stupid to do, it can have its uses)

5 Likes