The reason FindFirstChild is slower is primarily because there is some overhead to the mechanism behind it on top of the fact that .
indexes have gotten considerably faster in luau all around.
However, I really don’t recommend using :FindFirstChild()
OR the .
operator. You should almost always use :WaitForChild()
, while its probably the slowest of the three, you shouldn’t need to do this in a loop ever. The benefit is that you can rely on things being completely reliable regardless of how replication works, on top of the fact that you won’t run into property collisions, which I believe in the past has broken some games. If you’re using any of these you almost always only ever need to do it once (outside of functions).
:GetChildren()
is also quite fast, if not faster than indexing for higher child counts, though, I’ve not checked.
The exception is if you’re accessing children by variables as names, though, generally there are a lot better ways to do that, such as by mapping the instances you want to look at to their “names” with a hashmap somehow. You really shouldn’t be doing this regardless though unless you have no other option, since, this is hard to optimize. (Also, a["b"]
is significantly slower than a.b
in luau)
I have also noticed that for loops are as slow as the are. I’m not sure why its the case, but, you almost always seem to achieve better speeds if using a loop like so:
local i = 1
while i <= #table do -- Use ipairs, this is just an example
local child = table[1]
i += 1
end
I would assume this comes down to how it compiles, though, I really couldn’t tell you.
As for why ipairs and pairs are so much faster, its again, because of luau, both have been very very well optimized, its often times always faster to use ipairs so long as you have an existing table.
Lastly, the reason .Magnitude
is actually faster now is (shocker) because of luau again. The reason from what I can tell is basically that the largest portion of time actually comes from indexing. Everything else takes less time so, in the case of any of the rootless distance checks I could come up with in the post @XxELECTROFUSIONxX linked in their edit, since there are three indexes, the time is almost exactly 3x slower than .Magnitude
when you look at times over many iterations.
Also I’m fairly sure .Magnitude
is calculated upon the first index and cached, though, I can’t verify that. That’s what @SilentsReplacement was saying. This sort of behaviour is actually used a lot in the engine, every Roblox instance is a (special) userdata and has metatables, which has C metamethods. That’s generally how most lua based games work (and is also how Roblox works). When you index a property any sort of function-like behavior can happen before you get a result. I believe that that’s exactly how RobloxLocked instances work. In fact, I believe the way all class security stuff probably works is via those metamethods.