Hi, with my own benchmark against my own module, I found a fatal bug in your module that pretty much causes it to not execute functions after they yielded:
--!optimize 2
--!strict
-- yield test
local BadSignal = require(script.BadSignal)
local SignalX = require(script.SignalX)
local loops = 100
local Signal1 = BadSignal:new(1) -- 1 is to tell to make module dynamically allocate slots
local Signal2 = SignalX.new() -- empty to make it do the same as above
local t = os.clock()
for i = 1,loops do
Signal1:Push(true,function(b:any) -- true because there is a yielding function
local a = i*b::number
task.wait()
print("pTest1")
end)
end
print("Bad signal connect: ",os.clock()-t)
t = os.clock()
for i = 1,loops do
Signal2:Connect(function(b:any)
local a = i*b::number
task.wait()
print("pTest2")
end::any)
end
print("SignalX connect: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
Signal1:Fire(2)
end
print("Bad signal fire: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
Signal2:Fire(2)
end
print("SignalX fire: ",os.clock()-t)
The output in theory should have 1000 pTest1 and 1000 pTest2. But on tests there are only 1000 pTest1.
Also, I tested mine against non-yielding operations, and from the tests, once again, sometimes some of the functions don’t even fire:
--!optimize 2
--!strict
-- no yield test
local BadSignal = require(script.BadSignal)
local SignalX = require(script.SignalX)
local loops = 100
local Signal1 = BadSignal:new(1) -- 1 is to tell to make module dynamically allocate slots
local Signal2 = SignalX.new() -- empty to make it do the same as above
local t = os.clock()
for i = 1,loops do
Signal1:Push(false,function(b:any) -- false because there are no yielding functions
local a = i*b::number
print("pTest1")
end)
end
print("Bad signal connect: ",os.clock()-t)
t = os.clock()
for i = 1,loops do
Signal2:Connect(function(b:any)
local a = i*b::number
print("pTest2")
end::any)
end
print("SignalX connect: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
Signal1:Fire(2)
end
print("Bad signal fire: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
Signal2:Fire(2)
end
print("SignalX fire: ",os.clock()-t)
Bad signal connect: 0.0000092999980552122
SignalX connect: 0.00009100000170292333
▶ pTest1 (x1000)
Bad signal fire: 0.10646739999356214
▶ pTest2 (x600)
SignalX fire: 0.08270960000663763
As for cases when all of the functions fire, it loses against Bad Signal:
Bad signal connect: 0.000005299996701069176
SignalX connect: 0.00010699999984353781
▶ pTest1 (x1000)
Bad signal fire: 0.09846180000022287
▶ pTest2 (x1000)
SignalX fire: 0.10529619999579154
(Note that those are singleton tests; they can vary but most of the time Bad Signal wins.)