mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 06:22:26 +01:00
Datum Destroy Optimizing (#22693)
Some concerns were brought up about the potential for performance concerns with wrapping Destroy() in a try catch. So let me make a trade. /datum is the parent of all objects in existence, and is spending a large chunk of time on proc overhead for 2.6 million qdel'ed objects. <img width="1196" height="811" alt="image" src="https://github.com/user-attachments/assets/06ca1596-2d56-40ca-9ec6-9215ed02113c" /> I'll trade you a faster global destroy() for the better logging so I can finish destroying the garbage collector lag. The cost reduction is from 0.01209ms per datum to 0.007525ms per datum, about a 28% time saving.
This commit is contained in:
+43
-14
@@ -116,8 +116,37 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Cleanup all events on non-turfs. These used to be procs, but have been removed to save proc overhead on 2.6 million destroy() calls
|
||||
if (!isturf(src))
|
||||
cleanup_events(src)
|
||||
if(GLOB.global_listen_count && GLOB.global_listen_count[src])
|
||||
GLOB.global_listen_count -= src
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
if(event.unregister_global(src))
|
||||
log_debug("[event] - [src] was deleted while still registered to global events.")
|
||||
if(!(--GLOB.global_listen_count[src]))
|
||||
break
|
||||
if(GLOB.event_sources_count && GLOB.event_sources_count[src])
|
||||
GLOB.event_sources_count -= src
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
var/proc_owners = event.event_sources[src]
|
||||
if(proc_owners)
|
||||
for(var/proc_owner in proc_owners)
|
||||
if(event.unregister(src, proc_owner))
|
||||
log_debug("[event] - [src] was deleted while still being listened to by [proc_owner].")
|
||||
if(!(--GLOB.event_sources_count[src]))
|
||||
break
|
||||
if(GLOB.event_listen_count && GLOB.event_listen_count[src])
|
||||
GLOB.event_listen_count -= src
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
for(var/event_source in event.event_sources)
|
||||
if(event.unregister(event_source, src))
|
||||
log_debug("[event] - [src] was deleted while still listening to [event_source].")
|
||||
if(!(--GLOB.event_listen_count[src]))
|
||||
break
|
||||
// End of event cleanup
|
||||
|
||||
//BEGIN: ECS SHIT
|
||||
var/list/dc = _datum_components
|
||||
@@ -134,28 +163,28 @@
|
||||
qdel(C, FALSE)
|
||||
dc.Cut()
|
||||
|
||||
_clear_signal_refs()
|
||||
//END: ECS SHIT
|
||||
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
///Only override this if you know what you're doing. You do not know what you're doing
|
||||
///This is a threat
|
||||
/datum/proc/_clear_signal_refs()
|
||||
var/list/lookup = _listen_lookup
|
||||
if(lookup)
|
||||
for(var/sig in lookup)
|
||||
var/list/comps = lookup[sig]
|
||||
// Signal cleanup. This originally was a proc from /tg/ that had this warning label asking me not to override it.
|
||||
/*
|
||||
///Only override this if you know what you're doing. You do not know what you're doing
|
||||
///This is a threat
|
||||
*/
|
||||
// Well proc overhead is a thing that exists when you're qdel'ing 2.6 million objects. And NOTHING overrides it or has any reason to override it.
|
||||
if(length(_listen_lookup))
|
||||
for(var/sig in _listen_lookup)
|
||||
var/list/comps = _listen_lookup[sig]
|
||||
if(length(comps))
|
||||
for(var/datum/component/comp as anything in comps)
|
||||
comp.UnregisterSignal(src, sig)
|
||||
else
|
||||
var/datum/component/comp = comps
|
||||
comp.UnregisterSignal(src, sig)
|
||||
_listen_lookup = lookup = null
|
||||
_listen_lookup = null
|
||||
|
||||
for(var/target in _signal_procs)
|
||||
UnregisterSignal(target, _signal_procs[target])
|
||||
//END: ECS SHIT
|
||||
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/**
|
||||
* Callback called by a timer to end an associative-list-indexed cooldown.
|
||||
|
||||
@@ -2,14 +2,6 @@ GLOBAL_LIST_EMPTY(global_listen_count)
|
||||
GLOBAL_LIST_EMPTY(event_sources_count)
|
||||
GLOBAL_LIST_EMPTY(event_listen_count)
|
||||
|
||||
/proc/cleanup_events(source)
|
||||
if(GLOB.global_listen_count && GLOB.global_listen_count[source])
|
||||
cleanup_global_listener(source, GLOB.global_listen_count[source])
|
||||
if(GLOB.event_sources_count && GLOB.event_sources_count[source])
|
||||
cleanup_source_listeners(source, GLOB.event_sources_count[source])
|
||||
if(GLOB.event_listen_count && GLOB.event_listen_count[source])
|
||||
cleanup_event_listener(source, GLOB.event_listen_count[source])
|
||||
|
||||
/singleton/observ/register(datum/event_source, datum/listener, proc_call)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -39,33 +31,3 @@ GLOBAL_LIST_EMPTY(event_listen_count)
|
||||
if(GLOB.global_listen_count[listener] <= 0)
|
||||
GLOB.global_listen_count -= listener
|
||||
|
||||
/proc/cleanup_global_listener(listener, listen_count)
|
||||
GLOB.global_listen_count -= listener
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
if(event.unregister_global(listener))
|
||||
log_debug("[event] - [listener] was deleted while still registered to global events.")
|
||||
if(!(--listen_count))
|
||||
return
|
||||
|
||||
/proc/cleanup_source_listeners(event_source, source_listener_count)
|
||||
GLOB.event_sources_count -= event_source
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
var/proc_owners = event.event_sources[event_source]
|
||||
if(proc_owners)
|
||||
for(var/proc_owner in proc_owners)
|
||||
if(event.unregister(event_source, proc_owner))
|
||||
log_debug("[event] - [event_source] was deleted while still being listened to by [proc_owner].")
|
||||
if(!(--source_listener_count))
|
||||
return
|
||||
|
||||
/proc/cleanup_event_listener(listener, listener_count)
|
||||
GLOB.event_listen_count -= listener
|
||||
for(var/entry in GLOB.all_observable_events)
|
||||
var/singleton/observ/event = entry
|
||||
for(var/event_source in event.event_sources)
|
||||
if(event.unregister(event_source, listener))
|
||||
log_debug("[event] - [listener] was deleted while still listening to [event_source].")
|
||||
if(!(--listener_count))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user