Atmos init speedup, saves 4 seconds (#69697)

* Micro optimizes ssair's turf init, saving 2 seconds

Most of this is making existing operations do more legwork, or cheaper.
I did add cycle checking to ONLY init turf linking, which required
creating a new proc.
Did some horrible horrible things in said proc to save like 0.8 seconds.
I think it was worth it.
This commit is contained in:
LemonInTheDark
2022-09-06 02:53:46 -07:00
committed by GitHub
parent 259c72a68a
commit dff635b7f6
18 changed files with 165 additions and 100 deletions
+45 -7
View File
@@ -36,6 +36,9 @@ SUBSYSTEM_DEF(air)
var/list/gas_reactions = list()
var/list/atmos_gen
var/list/planetary = list() //Lets cache static planetary mixes
/// List of gas string -> canonical gas mixture
var/list/strings_to_mix = list()
//Special functions lists
var/list/turf/active_super_conductivity = list()
@@ -521,7 +524,7 @@ SUBSYSTEM_DEF(air)
/datum/controller/subsystem/air/proc/setup_allturfs()
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
var/list/active_turfs = src.active_turfs
var/times_fired = ++src.times_fired
times_fired++
// Clear active turfs - faster than removing every single turf in the world
// one-by-one, and Initalize_Atmos only ever adds `src` back in.
@@ -531,13 +534,16 @@ SUBSYSTEM_DEF(air)
active.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, COLOR_VIBRANT_LIME)
#endif
active_turfs.Cut()
var/time = 0
for(var/thing in turfs_to_init)
var/turf/T = thing
if (T.blocks_air)
for(var/turf/T as anything in turfs_to_init)
if (!T.init_air)
continue
T.Initalize_Atmos(times_fired)
CHECK_TICK
// We pass the tick as the current step so if we sleep the step changes
// This way we can make setting up adjacent turfs O(n) rather then O(n^2)
T.Initalize_Atmos(time)
if(CHECK_TICK)
time++
if(active_turfs.len)
var/starting_ats = active_turfs.len
@@ -561,8 +567,8 @@ SUBSYSTEM_DEF(air)
active_turfs += new_turfs_to_check
turfs_to_check = new_turfs_to_check
while (turfs_to_check.len)
var/ending_ats = active_turfs.len
for(var/thing in excited_groups)
var/datum/excited_group/EG = thing
@@ -663,6 +669,38 @@ GLOBAL_LIST_EMPTY(colored_images)
var/datum/atmosphere/atmostype = T
atmos_gen[initial(atmostype.id)] = new atmostype
/// Takes a gas string, returns the matching mutable gas_mixture
/datum/controller/subsystem/air/proc/parse_gas_string(gas_string)
var/datum/gas_mixture/cached = strings_to_mix[gas_string]
if(cached)
if(istype(cached, /datum/gas_mixture/immutable))
return cached
return cached.copy()
var/datum/gas_mixture/canonical_mix = new()
// We set here so any future key changes don't fuck us
strings_to_mix[gas_string] = canonical_mix
gas_string = preprocess_gas_string(gas_string)
var/list/gases = canonical_mix.gases
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
canonical_mix.temperature = text2num(gas["TEMP"])
canonical_mix.temperature_archived = canonical_mix.temperature
gas -= "TEMP"
else // if we do not have a temp in the new gas mix lets assume room temp.
canonical_mix.temperature = T20C
for(var/id in gas)
var/path = id
if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
ADD_GAS(path, gases)
gases[path][MOLES] = text2num(gas[id])
if(istype(canonical_mix, /datum/gas_mixture/immutable))
return canonical_mix
return canonical_mix.copy()
/datum/controller/subsystem/air/proc/preprocess_gas_string(gas_string)
if(!atmos_gen)
generate_atmos()