Have you seen the benchmark from VortechBirb?
Even v2.2.0 was significantly faster than GoodSignal.
The newest version at the moment is v2.6.0.
Here’s VortechBirb’s benchmark with Signal+ v2.2.0 (old):
Faster than GoodSignal? Sure.
Faster than Signal+? Think again.
Benchmark:
Create 100 signals:
Signal+ measured at 0.0034189999496447854 milliseconds
SimpleSignal measured at 0.007416999887936981 milliseconds Signal+ was 0.003997999938292196 milliseconds (~2.17x) faster than SimpleSignal
Connect 100 functions:
Signal+ measured at 0.010097000013047364 milliseconds
SimpleSignal measured at 0.018533000020397594 milliseconds Signal+ was 0.00843600000735023 milliseconds (~1.84x) faster than SimpleSignal
Fire with 100 functions:
Signal+ measured at 0.03844200000457931 milliseconds
SimpleSignal measured at 0.04617999997208244 milliseconds Signal+ was 0.007737999967503129 milliseconds (~1.2x) faster than SimpleSignal
Once 100 functions:
Signal+ measured at 0.016663000005792128 milliseconds
SimpleSignal measured at 0.024316000071848975 milliseconds Signal+ was 0.007653000066056848 milliseconds (~1.46x) faster than SimpleSignal
Disconnect 100 functions:
Signal+ measured at 0.009299999874201603 milliseconds
SimpleSignal measured at 0.014799999917158857 milliseconds Signal+ was 0.005500000042957254 milliseconds (~1.59x) faster than SimpleSignal
Disconnect all with 100 functions:
Signal+ measured at 0.0008999995770864189 milliseconds
SimpleSignal measured at 0.010800000382005237 milliseconds Signal+ was 0.009900000804918818 milliseconds (~12x) faster than SimpleSignal
I ran each test 100 times (e.g. 100 connections 100 times), and the measurements are average run time. You are free to test yourself, but I think it’s really clear who’s the winner in that benchmark.
Signal+ measured at 0.0028682000023763973 milliseconds
SimpleSignal measured at 0.006316119998336944 milliseconds Signal+ was 0.0034479199959605465 milliseconds (~2.2x) faster than SimpleSignal
Connect 100 functions:
Signal+ measured at 0.011354389998450643 milliseconds
SimpleSignal measured at 0.039814160002242714 milliseconds Signal+ was 0.028459770003792073 milliseconds (~3.51x) faster than SimpleSignal
Fire with 100 functions:
Signal+ measured at 0.03842830000940012 milliseconds
SimpleSignal measured at 1.4735136999843235 milliseconds Signal+ was 1.4350853999749233 milliseconds (~38.34x) faster than SimpleSignal
Once 100 functions:
Signal+ measured at 0.03111915999525081 milliseconds
SimpleSignal measured at 0.05852859000151511 milliseconds Signal+ was 0.027409430006264304 milliseconds (~1.88x) faster than SimpleSignal
Disconnect 100 functions:
Signal+ measured at 0.007469740002306935 milliseconds
SimpleSignal measured at 0.023178689999440394 milliseconds Signal+ was 0.01570894999713346 milliseconds (~3.1x) faster than SimpleSignal
Disconnect all with 100 functions:
Signal+ measured at 0.003145279998352635 milliseconds
SimpleSignal measured at 0.013685699996858602 milliseconds Signal+ was 0.010540419998505968 milliseconds (~4.35x) faster than SimpleSignal
Signal+ measured at 0.0029365899961703687 milliseconds
LemonSignal measured at 0.004803160001574725 milliseconds Signal+ was 0.001866570005404356 milliseconds (~1.64x) faster than LemonSignal
Connect 100 functions:
Signal+ measured at 0.013497720008854231 milliseconds
LemonSignal measured at 0.025186950003444508 milliseconds Signal+ was 0.011689229994590277 milliseconds (~1.87x) faster than LemonSignal
Fire with 100 functions:
Signal+ measured at 0.042660700009946595 milliseconds
LemonSignal measured at 0.041893600044204504 milliseconds LemonSignal was 0.0007670999657420907 milliseconds (~1.02x) faster than Signal+
Once 100 functions:
Signal+ measured at 0.028835559998151437 milliseconds
LemonSignal measured at 0.04398460000320483 milliseconds Signal+ was 0.015149040005053394 milliseconds (~1.53x) faster than LemonSignal
Disconnect 100 functions:
Signal+ measured at 0.007742059994416195 milliseconds
LemonSignal measured at 0.0053807700047400426 milliseconds LemonSignal was 0.0023612899896761526 milliseconds (~1.44x) faster than Signal+
Disconnect all with 100 functions:
Signal+ measured at 0.0036735600029714987 milliseconds
LemonSignal measured at 0.00356048000685405 milliseconds LemonSignal was 0.00011307999611744881 milliseconds (~1.03x) faster than Signal+
And here’s FastSignal btw:
Create 100 signals:
Signal+ measured at 0.002846440000575967 milliseconds
FastSignal measured at 0.005018470000504749 milliseconds Signal+ was 0.002172029999928782 milliseconds (~1.76x) faster than FastSignal
Connect 100 functions:
Signal+ measured at 0.012557659999765746 milliseconds
FastSignal measured at 0.03306501000042772 milliseconds Signal+ was 0.02050735000066197 milliseconds (~2.63x) faster than FastSignal
Fire with 100 functions:
Signal+ measured at 0.041073800004596706 milliseconds
FastSignal measured at 0.0390601999934006 milliseconds FastSignal was 0.002013600011196104 milliseconds (~1.05x) faster than Signal+
Once 100 functions:
Signal+ measured at 0.024617289999696368 milliseconds
FastSignal measured at 0.03905997000711068 milliseconds Signal+ was 0.014442680007414312 milliseconds (~1.59x) faster than FastSignal
Disconnect 100 functions:
Signal+ measured at 0.007536460004666878 milliseconds
FastSignal measured at 0.005873989997417084 milliseconds FastSignal was 0.0016624700072497937 milliseconds (~1.28x) faster than Signal+
Disconnect all with 100 functions:
Signal+ measured at 0.0032694300036382627 milliseconds
FastSignal measured at 0.0041916699979992695 milliseconds Signal+ was 0.0009222399943610068 milliseconds (~1.28x) faster than FastSignal
Overall Signal+ is the winner (faster than FastSignal and LemonSignal) — if you take the total speeds.
These are some benchmarks sent by a friend of mine after I shared this resource
The difference is miniscule for the functions, (except :Connect(), tho that might just be some flaws in how my friend benchmarked it) and for :Fire() it’s faster.
Since you didn’t share how you did your benchmarks, I’m a bit skeptical as to wether or not they’re real.
Will be doing my own benchmarks when I can
Provide context as to what these numbers mean, is it total? (I think it is because you said “total speeds”), is it the mean? Is it the median? Just to clear any doubt in anyones mind
Dude, stop replying to @athar_adv on some of his replies he is not being serious and he just posted benchmarks that ironically still show the module is faster, by his logic his benchmarks can’t be trusted either.
The difference is literally microseconds for most functions
I also shared how the benchmarks were done
Who has 100 connections on 1 signal anyway…
Heres some more benchmarks comparing SimpleSignal and FastSignal (My friends own Signal implementation, not to be confused with the same named FastSignal)
It’s even faster than both SimpleSignal and SignalPlus
Honesty I don’t really mind trying to develop a resource, I get that, just try being more transparent so people can see for themselves if your resource holds water or not instead of only making claims
You’re talking about unclear benchmarks, and you provide a benchmark where half of the results are just called Create, Fire, Connect, instead of the actual module names.
I benchmarked against FastSignal, and trust me I did it properly, and Signal+ won.
May I ask why you can’t accept that Signal+ is at least faster in 80% of scenarios?
Stop making weird conclusions, trying to promote you and your friend’s work.
You can trust my benchmark because I gave the code for it so you can test it out for yourself :v
Also mine has pictures… idk if its relevant but imo more believable than numbers in text
This is what I used for Good-, Lemon- and FastSignal benchmarks.
Just change the OtherSignalModule to require the desired module.
You shouldn’t have to change anything because they all share the same syntax.
Signal+ vs other signal module benchmark
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local function difference(a, b)
if b < a then
return a - b
else
return b - a
end
end
local function benchmark(funcs, runs)
if type(runs) ~= "number" or runs <= 1 then runs = nil end
local function measure(func)
if not runs then
-- Run only once.
local start = os.clock()
func()
return os.clock() - start
else
-- Run specified amount of times.
local sum = 0
for index = 1, runs, 1 do
local start = os.clock()
func()
sum += os.clock() - start
end
return sum/runs -- Calculate average run time.
end
end
local output = ""
local one = measure(funcs[1])*1000
local two = measure(funcs[2])*1000
local diff = difference(one, two)
local fastest = if two < one then two else one
if diff < fastest*0.001 then
-- Basically identical speeds.
output ..= "\n⚖️ Both functions measured at "..tostring(fastest+diff/2).." milliseconds\n"
else
output ..= "\nFunction 1 measured at "..tostring(one).." milliseconds"
output ..= "\nFunction 2 measured at "..tostring(two).." milliseconds"
if two == fastest then
output ..= "\n🏆 Function 2 was "..tostring(diff).." milliseconds (~"..tostring(math.round(one/two*100)/100).."x) faster than function 1\n"
else
output ..= "\n🏆 Function 1 was "..tostring(diff).." milliseconds (~"..tostring(math.round(two/one*100)/100).."x) faster than function 2\n"
end
end
warn(output)
end
task.wait(5)
local signalPlusCreate = require(ReplicatedStorage.SignalPlus)
local otherSignalModule = require(ReplicatedStorage.SimpleSignal)
print("Create 100 signals:")
benchmark(
{
function()
for index = 1, 100, 1 do
signalPlusCreate()
end
end,
function()
for index = 1, 100, 1 do
otherSignalModule.new()
end
end
},
10000
)
local signalPlus = signalPlusCreate()
local otherSignal = otherSignalModule.new()
print("Connect 100 functions:")
benchmark(
{
function()
for index = 1, 100, 1 do
signalPlus:Connect(function() end)
end
end,
function()
for index = 1, 100, 1 do
otherSignal:Connect(function() end)
end
end
},
10000
)
signalPlus:DisconnectAll()
otherSignal:DisconnectAll()
for index = 1, 100, 1 do
signalPlus:Connect(function() end)
end
for index = 1, 100, 1 do
otherSignal:Connect(function() end)
end
print("Fire with 100 functions:")
benchmark(
{
function()
signalPlus:Fire()
end,
function()
otherSignal:Fire()
end
},
1000
)
print("Once 100 functions:")
benchmark(
{
function()
for index = 1, 100, 1 do
signalPlus:Once(function() end)
end
end,
function()
for index = 1, 100, 1 do
otherSignal:Once(function() end)
end
end
},
10000
)
signalPlus:DisconnectAll()
otherSignal:DisconnectAll()
print("Disconnect 100 functions:")
local signalPlusTable = {}
for index = 1, 100*10000, 1 do
table.insert(signalPlusTable, signalPlus:Connect(function() end))
end
local simpleSignalTable = {}
for index = 1, 100*10000, 1 do
table.insert(simpleSignalTable, otherSignal:Connect(function() end))
end
local signalPlusCurrent = 1
local otherSignalCurrent = 1
benchmark(
{
function()
for index = signalPlusCurrent, signalPlusCurrent + 99, 1 do
signalPlusTable[index]:Disconnect()
end
signalPlusCurrent += 100
end,
function()
for index = otherSignalCurrent, otherSignalCurrent + 99, 1 do
simpleSignalTable[index]:Disconnect()
end
otherSignalCurrent += 100
end
},
10000
)
print("Disconnect all with 100 functions:")
local signalPlusses = {}
for index = 1, 10000, 1 do
local signal = signalPlusCreate()
for index = 1, 100, 1 do
signal:Connect(function() end)
end
table.insert(signalPlusses, signal)
end
local otherSignals = {}
for index = 1, 10000, 1 do
local signal = otherSignalModule.new()
for index = 1, 100, 1 do
signal:Connect(function() end)
end
table.insert(otherSignals, signal)
end
local signalPlusIndex = 1
local otherSignalIndex = 1
benchmark(
{
function()
signalPlusses[signalPlusIndex]:DisconnectAll()
signalPlusIndex += 1
end,
function()
otherSignals[otherSignalIndex]:DisconnectAll()
otherSignalIndex += 1
end
},
10000
)