Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

More efficient yielding?

So on the ROBLOX scripting forum I discussed better wait functions with the forum because I was bored, and we ended up with this:

function yield(t)
local before=tick()
local now=tick()
repeat now=tick() until (now-before)>=t
return t
end

I wanted to know if I could make this even more efficient. I think this currently works great, I'm not sure if it's as fast as RenderStepped, though. Thoughts?

1 answer

✓ Accepted answer

I would recommend at least writing it a little neater:

function sleep(t)
	local stop = tick() + t
	while tick() < stop do end
end

This is called busy-waiting. It's a bad idea, because it prevents all other code from being executed, and also taxes the CPU.

On the other hand, it's easy to implement, and if you don't need other code to be running, that might be OK.

What you should do instead

You want to actually use wait or one of its friends, so that the CPU isn't pegged by busy-waiting.

How those work is by yielding the current coroutine with coroutine.yield, and then resuming it at a later time using coroutine.resume. All of the functions like wait, :wait on events, etc. use this.

You can take advantage of them to make this function not busy-wait, but there's no real reason to.


Almost always you'd want to use either plain old wait (if you're going to take more than 30th of a second) or otherwise RenderStepped (because you can't take less).

Amending the sleep function to call these makes it much safer:

function sleep(t)
	local stop = tick() + t
	while tick() < stop do
		wait()
		-- OR
		game:GetService("RunService").RenderStepped:wait()
	end
end

7 comments

0

I don't see why you would use wait() as RenderStepped is literally an instance, and the goal of this is to make it wait a more precise amount of time. Good explanation though.

2

RenderStepped is not an instance. It is an event. Using the 'wait' method on the syntax for an event will prevent the script from continuing until the event is met. Using wait() will perhaps at most get you 1/30th of a second while RenderStepped can be relied on to get near 1/60th of a second intervals.

0

1/60th a second is basically an instance or a frame, but if it's "near" then my mistake, not literally, almost?

0

Careful with the word 'instance' because in Roblox that word is very eclectic.

0

@drahsid5: RenderStepped fires every frame. Usually, this will be fairly precisely 1/60th of a second. It will be slow if your frame rate is slower or the window is not focused.

0

@Blue Yes, I know, ROBLOX's framerate is actually very weird, It uses a VSync but is never exactly 60 FPS, even on my GTX 980, rather hanging around 59-61. Can ROBLOX go above 60 FPS on higher refresh rate monitors?

0

I'm not sure, but that's not a fact that should ever concern you as a script-writer. RenderStepped is as fast as possible, and all code should explicitly take into account the actual elapsed time, not just the time you thought it will be.

This discussion is preserved as it was. New answers, comments, and votes are closed.