This seems like an issue of having different hardware in that case. I don’t really bother comparing stuff at such a level, since it’s very prone to illusionary and misleading results - the only reason I compared this module with Roblox’s is that the margin of error is small enough in comparison to Roblox’s “failure rate”, and as such the margin of error can be ignored completely. With modules that provide very similar results with only the slightest differences, it’s hard to say what’s truly the better option. I’ll run both scripts though the micro-profiler and also boatbomber’s benchmarker plugin instead, as they provide with more accurate results.
That’s weird. I’ve confirmed this behavior just now, and it does seem like wait(0) or wait() achieve this effect. An easy solution would be to just do wait(0.01) for now. I’ll fix this next update and clamp the minimum value to 0.01.
Best != perfect. Don’t mix up the words. Thus far I have not seen any solution which other modules offer better solutions than this module. You mentioned your own module with no other relevancy other than to imply it is better than mine because the issue mentioned above does not occur with yours. Before you state that you didn’t say that, I meant imply. Intent is enough, and saying that was not your intent would be delusional.
This loops us back to the previous debate - code performs and scales differently on different machines. There is no one absolute, and I’m not that interested in results that could be biased depending on what machine it was ran.
Either way, since both utilize custom task schedulers they are already optimized out well enough. The only difference you would see between the two would be when running both > 10^7 times, which would never occur in any productive code.
Also, sorry for being rude in the previous reply. I was rather heated towards the reply.
I mean… I’m unsure as to why you’d wanna do that, but a quick workaround would be:
local Yielded = {}
local function WrappedWait(n)
Yielded[coroutine.running()] = true
local a,b = RBXWait(n)
Yielded[coroutine.running()] = nil
return a, b
end
local function UnyieldAll()
for Thread in next, Yielded do
coroutine.resume(Thread)
end
table.clear(Yielded)
end
I had some rare use cases of disabling the script (with a loop inside) from the outside, but they were a long time ago and were perhaps just bad coding practice.
But the script performance one is still kind of relevant when measuring efficiency of scripts.
Hey, I’m having an issue with the module. It seems whenever I use multiple wait() at the same time, all of them will wait for the amount of time that was longest. I dumped the source code into a module called Wait2 and then ran this code:
local t = tick()
local wait2 = require(game.ReplicatedStorage.Modules.Wait2)
coroutine.wrap(function()
wait2(3)
end)()
wait2(1)
print(tick() - t)
The print will always spout a number around 3.
The code used in the module:
local heap = {}
local currentSize = 0
function insert(yieldTime, data)
currentSize += 1
local start = time()
heap[currentSize] = {
pos = start - yieldTime,
data = data,
time = start
}
-- bubble up
local pos = currentSize
local parentIdx = math.floor(pos/2)
local currentIdx = pos
while currentIdx > 1 and start-heap[parentIdx].pos < start-heap[currentIdx].pos do
heap[currentIdx], heap[parentIdx] = heap[parentIdx], heap[currentIdx]
currentIdx = parentIdx
parentIdx = math.floor(parentIdx/2)
end
end
function extractMin()
if currentSize < 2 then
heap[1] = nil
currentSize = 0
return
end
heap[1], heap[currentSize] = heap[currentSize], nil
-- sink down
local k = 1
local start = time()
while k < currentSize do
local smallest = k
local leftChildIdx = 2*k
local rightChildIdx = 2*k+1
if leftChildIdx < currentSize and start-heap[smallest].pos < start-heap[leftChildIdx].pos then
smallest = leftChildIdx
end
if rightChildIdx < currentSize and start-heap[smallest].pos < start-heap[rightChildIdx].pos then
smallest = rightChildIdx
end
if smallest == k then
break
end
heap[k], heap[smallest] = heap[smallest], heap[k]
k = smallest
end
currentSize -= 1
end
game:GetService('RunService').Stepped:Connect(function()
local PrioritizedThread = heap[1]
if not PrioritizedThread then
return
end
local start = time()
-- while true do loops could potentially trigger script exhaustion, if you were to have >50k yields for some reason...
for _ = 1, 10000 do
local YieldTime = start - PrioritizedThread.time
if PrioritizedThread.data[2] - YieldTime <= 0 then
extractMin()
coroutine.resume(PrioritizedThread.data[1], YieldTime, start)
PrioritizedThread = heap[1]
if not PrioritizedThread then
break
end
else
break
end
end
end)
return function(Time)
Time = (type(Time) ~= 'number' or Time <= 0) and 0.001 or Time
insert(Time, {coroutine.running(), Time})
return coroutine.yield()
end