[MIRROR] Micro-optimizes _SendSignal a bit (#27759)

* Micro-optimizes _SendSignal a bit (#83244)

## About The Pull Request
Instead of iterating over an assoc list and doing a list access, which
has a complexity of O(nlog(n)), it is better to just store a 2 tuple and
access that to get a complexity of O(n)
Check code to see what I mean.

## Why It's Good For The Game

![image](https://github.com/tgstation/tgstation/assets/37270891/1e5d68fa-2e19-473c-a870-e1e0277cbacc)
This is a very hot proc and it's worth micro-optimizing where we can.

The speed increase in doing the following code can be seen here:

![image](https://github.com/tgstation/tgstation/assets/37270891/1b7f00a3-b3c2-4976-b2ab-97eefbbd2459)
Higher is better.

The code that was benchmarked:
```dm
var/list/target = list()

/proc/testa()
    var/list/queued_calls = list()
    for(var/i in 1 to length(target))
        var/data = target[i]
        queued_calls.Add(data, 1)
    for(var/i in 1 to (length(queued_calls) / 2))
        var/a = queued_calls[i*2-1]
        var/b = queued_calls[i*2]

/proc/testb()
    var/list/queued_calls = list()
    for(var/data in target)
        queued_calls[data] = 1
    for(var/data in queued_calls)
        var/a = data
        var/b = queued_calls[data]

MAIN
	for(var/i in 1 to 100)
		target.Add("[i]")
    BEGIN_BENCH(2)
        BENCH_PHASE("New code", testa())
        BENCH_PHASE("Old code", testb())
    END_BENCH
```

## Changelog

---------

Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@ users.noreply.github.com>

* Micro-optimizes _SendSignal a bit

---------

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@ users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-05-18 03:17:14 +02:00
committed by GitHub
co-authored by Watermelon914 LemonInTheDark Watermelon914
parent fcf3b20e92
commit 0d0ec78ef2
+6 -4
View File
@@ -120,7 +120,9 @@
// all the objects that are receiving the signal get the signal this final time.
// AKA: No you can't cancel the signal reception of another object by doing an unregister in the same signal.
var/list/queued_calls = list()
for(var/datum/listening_datum as anything in target)
queued_calls[listening_datum] = listening_datum._signal_procs[src][sigtype]
for(var/datum/listening_datum as anything in queued_calls)
. |= call(listening_datum, queued_calls[listening_datum])(arglist(arguments))
// This should be faster than doing `var/datum/listening_datum as anything in target` as it does not implicitly copy the list
for(var/i in 1 to length(target))
var/datum/listening_datum = target[i]
queued_calls.Add(listening_datum, listening_datum._signal_procs[src][sigtype])
for(var/i in 1 to length(queued_calls) step 2)
. |= call(queued_calls[i], queued_calls[i + 1])(arglist(arguments))