Making Best Wait Testing Script

Hello all,
Today I was trying to make a script to test the best way to wait. Currently I have found 2 different wait scripts that work with the module. But I was trying to test more normal wait functions instead it just doesn’t work.

Wait Testing Script
--Made by StrategicPlayZ

local Module = require(game:GetService("ReplicatedStorage").ModuleGoesHere)

for i = 5,1,-1 do
	print("[STARTING BENCHMARK IN " .. i .. "s]")
	wait(1)
end

local total = 50000
local wait_time = 1

local benchmark_func = Module do
	print("...[BENCHMARK BEGIN]...")

	local num_failed = 0
	local total_wait = 0
	local highest_wait = 0
	local lowest_wait = math.huge

	local completed

	game:GetService("RunService").Stepped:Wait()

	for index = 1, total do
		coroutine.wrap(function()
			local taken_time = benchmark_func(wait_time)
			if ((taken_time > (wait_time + 0.04)) or (taken_time < (wait_time - 0.04))) then
				num_failed += 1
			end
			if (taken_time > highest_wait) then
				highest_wait = taken_time
			end
			if (taken_time < lowest_wait) then
				lowest_wait = taken_time
			end
			total_wait += taken_time
			completed()
		end)()
	end

	do
		local n = 0
		function completed()
			n += 1
			if (n ~= total) then return end

			local average_wait = (total_wait / total)

			print("[% NUM FAILED]: " .. (num_failed / total * 100) .. "%")
			print("[AVERAGE WAIT]: " .. average_wait)
			print("[HIGHEST WAIT]: " .. highest_wait)
			print("[LOWEST  WAIT]: " .. lowest_wait)
		end
	end
end
One Wait Module that works with the script

– // By StrategicPlayZ \ –

local RunService = game:GetService("RunService")

-- Thread/Yield storage
local threads = {}
local n_threads = 0

RunService.Stepped:Connect(function(_, delta_time)
	-- Do not execute if no yields are present
	if (n_threads == 0) then return end

	-- Get the [current_time]
	local current_time = os.clock()

	-- Loop through all the running yields
	local thread_index = 1
	while (thread_index < n_threads) do
		-- Fetch the [thread] and its [resume_time]
		local resume_time_index = (thread_index + 1)

		local thread, resume_time = threads[thread_index], threads[resume_time_index]

		-- If the current [index] is nil then break out of the loop
		if (not thread) then break end

		-- Time elapsed since the current yield was started
		local difference = (resume_time - current_time)

		-- If the yield has been completed
		if (difference <= 0) then
			-- Remove it from [threads] table
			if (resume_time_index ~= n_threads) then
				threads[thread_index] = threads[n_threads - 1]
				threads[resume_time_index] = threads[n_threads]

				threads[n_threads - 1] = nil
				threads[n_threads] = nil

				n_threads -= 2

				-- Resume the [thread] (stop the yield)
				coroutine.resume(thread, current_time)

				continue
			else
				threads[thread_index] = nil
				threads[resume_time_index] = nil

				n_threads -= 2

				-- Resume the [thread] (stop the yield)
				coroutine.resume(thread, current_time)
			end
		end
		thread_index += 2
	end
end)

-- Main function that is executed when the module is used
local default_wait = 0
local function FastWait(wait_time)
	-- Verifies [wait_time]
	wait_time = tonumber(wait_time) or (default_wait)

	-- Mark [start] time
	local start = os.clock()

	-- Get running [thread]
	local thread = coroutine.running()

	-- Insert it in [threads] table
	threads[n_threads + 1] = thread
	threads[n_threads + 2] = (start + wait_time)

	n_threads += 2

	-- Wait until the coroutine resumes (the yielding finishes)
	local current_time = coroutine.yield()

	-- Return: (time_it_waited, current_time)
	return (current_time - start), current_time
end

return FastWait
Another Wait Module that works with the script
local o_clock = os.clock
local c_yield = coroutine.yield
local c_running = coroutine.running
local c_resume = coroutine.resume

local Yields = {}
game:GetService('RunService').Stepped:Connect(function()
	local Clock = o_clock()
	for Idx, data in next, Yields do
		local Spent = Clock - data[1]
		if Spent >= data[2] then
			Yields[Idx] = nil
			c_resume(data[3], Spent, Clock)
		end
	end
end)

return function(Time)
	Time = (type(Time) ~= 'number' or Time < 0) and 0 or Time
	table.insert(Yields, {o_clock(), Time, c_running()})
	return c_yield()
end
My Module that wont work with the script
--Made by Tomroblox54321
local MyWaitModule = {}
local RunService = game:GetService("RunService")

local DefaultWait = 0

function MyWaitModule:TaskWait(Number : number)
	local WaitNumberToWait = tonumber(Number)  or (DefaultWait)
	task.wait(WaitNumberToWait)
end



function MyWaitModule:HeartbeatWait(Number : number)
	local WaitNumberToWait = tonumber(Number)  or (DefaultWait)
	local HeartbeatWaitNumber RunService.Heartbeat:Wait(WaitNumberToWait)
end


function MyWaitModule:SteppedWait(Number:number)
	local WaitNumber = tonumber(Number)  or (DefaultWait)
	RunService.Stepped:Wait(WaitNumber)
end

function MyWaitModule:RenderSteppedWait(Number : number)
	local WaitNumber = tonumber(Number)  or (DefaultWait)
	RunService.RenderStepped:Wait(WaitNumber)
end

function MyWaitModule:Wait(Number : number)
	local WaitNumber = tonumber(Number)  or (DefaultWait)
	wait(WaitNumber)
end


return MyWaitModule

Thanks for helping all!

Why do you need this exactly?

Roblox recently released their new task library which contains better optimized yielding functions, which incorporate some of these RunService events I believe.

I want this because I want to test how much better different wait functions perform. Then I want to share this with the community to help with game development.

I believe there are already answers to this, try checking out some previously made posts first.

I use Promises by @evaera, and it is by far better than any I had used.

Thanks everyone for helping I’ll try it out