A Better Way for ELS Community to Optimize ELS Codes for Performance

me ranting about while true do loops with RunService.____:Wait

One interesting thing to note is that while true do RunService.Event:Wait() end is not only bad because it’s a infinite while loop, but also because a :Wait call to a RBXScriptSignal needs to allocate memory for a linked list node.

:Wait really just makes a connection, yields the thread it’s being called from, and disconnects it once :Fire is called and resumes the thread with the arguments passed through.

Memory allocation every frame is a no-no. It’s nice to point out that the garbage collector/allocator will reuse memory from stuff that has been gced, that’s how it works, but it’s still for me a big no-no for me because even then, you are still creating a linked list node each frame, just to disconnect it right after.

If you’re using task.wait / wait you basically have the same issue just with a different story behind it. You shouldn’t have an issue with bigger numbers.

while true do
    -- ...

    RunService.Heartbeat:Wait()
end

Is not that much better than:

while true do
    -- ...

    task.wait()
end

But,

RunService.Heartbeat:Connect(function()
    -- ...
end)

Is much better than all alternatives above.

This :Wait allocation thing is not even the biggest reason why those loops are bad, not even close, but I wanted to point that out since I’ve been looking into event-driven code for a long time.

while true do
    RareEvent:Wait() -- Event that fires only here and there, isn't a per-frame thing.

    -- ...
end

Is not that bad if you’re trying to yield a thread while doing something, but when you don’t want to yield the thread, then just use :Connect!!!

While probably not as useful in all this ELS business, you can always create custom ScriptSignals, which makes things a lot easier and helps you get rid of polling in overall code design.

3 Likes