Faster server startup (#32861)

* Faster object initialisations

* Faster station alert computers

* Removes sleeps in this too, now shaving another 3 seconds off

* Entered

* These work just fine as spawns instead of sleeps, no delays

* Changing this threshold, not much stuff shows up anymore taking longer than 1 tick

* Some logging

* Makes vaults load much faster

* Better like this

* Makes lightspeed ship load much faster

Co-authored-by: kanef <kanef9x@protonmail.com>
This commit is contained in:
kane-f
2022-07-01 13:09:20 +01:00
committed by GitHub
parent fec5281bb9
commit 25ef28e54d
11 changed files with 85 additions and 60 deletions

View File

@@ -36,19 +36,19 @@
if(open)
return 0
update_icon(0,1) //animate
sleep(10)
open = TRUE
update_icon()
update_icon(0,1)
spawn(10)
open = TRUE
update_icon()
if(network1&&network2)
network1.merge(network2)
network2 = network1
if(network1&&network2)
network1.merge(network2)
network2 = network1
if(network1)
network1.update = 1
else if(network2)
network2.update = 1
if(network1)
network1.update = 1
else if(network2)
network2.update = 1
return 1
@@ -56,19 +56,19 @@
if(!open)
return 0
update_icon(0,1) //animate
sleep(10)
open = FALSE
update_icon()
update_icon(0,1)
spawn(10)
open = FALSE
update_icon()
if(network1)
if(network1)
qdel(network1)
if(network2)
if(network1)
qdel(network2)
if(network1)
qdel(network1)
if(network2)
if(network1)
qdel(network2)
build_network()
build_network()
return 1

View File

@@ -46,13 +46,14 @@
if(config.log_admin_only)
admin_diary << html_decode(text_to_log)
/proc/log_debug(text)
/proc/log_debug(text, send2chat = TRUE)
if (!config || config.log_debug) // Sorry, if config isn't loaded we'll assume you want debug output.
diary << html_decode("\[[time_stamp()]]DEBUG: [text]")
for(var/client/C in admins)
if(C.prefs.toggles & CHAT_DEBUGLOGS)
to_chat(C, "DEBUG: [text]")
if(send2chat)
for(var/client/C in admins)
if(C.prefs.toggles & CHAT_DEBUGLOGS)
to_chat(C, "DEBUG: [text]")
/proc/log_sql(text)
if (!config || (config && config.log_sql))

View File

@@ -130,7 +130,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// Sort subsystems by init_order, so they initialize in the correct order.
sortTim(subsystems, /proc/cmp_subsystem_init)
var/time_to_init = world.time
var/time_to_init = world.timeofday
// Initialize subsystems.
CURRENT_TICKLIMIT = TICK_LIMIT_MC_INIT
for (var/datum/subsystem/SS in subsystems)
@@ -139,7 +139,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
SS.Initialize(world.timeofday)
CHECK_TICK
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
time_taken_to_init = world.time - time_to_init
time_taken_to_init = world.timeofday - time_to_init
to_chat(world, "<span class='boldannounce'>Initializations complete in [time_taken_to_init / 10] seconds!</span>")
world.log << "Initializations complete. Took [time_taken_to_init / 10] seconds."

View File

@@ -156,7 +156,8 @@
/datum/subsystem/proc/Initialize(start_timeofday)
var/time = (world.timeofday - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] seconds!"
log_debug(msg)
log_debug(msg,FALSE) // Redundant chat output as whole world sees message below anyways
world.log << msg
to_chat(world, "<span class='danger'>[msg]</span>")
initialized = TRUE
return time

View File

@@ -24,7 +24,7 @@ var/list/processing_objects = list()
var/time_start = world.timeofday
object.initialize()
var/time = (world.timeofday - time_start)
if(time > 1 SECONDS)
if(time > 1) // At this point very few items (such as corpse landmarks) take longer than a tick to init, with the main bulk of items taking around 1 tick being things that use relativewall()
var/turf/T = get_turf(object)
log_debug("Slow object initialize. [object] ([object.type]) at [T?.x],[T?.y],[T?.z] took [time/10] seconds to initialize.")
else

View File

@@ -8,6 +8,7 @@ var/area/space_area
var/global/global_uid = 0
var/uid
var/obj/machinery/power/apc/areaapc = null
var/list/obj/machinery/alarm/air_alarms = list()
var/list/area_turfs
plane = ABOVE_LIGHTING_PLANE
layer = MAPPING_AREA_LAYER
@@ -187,7 +188,7 @@ var/area/space_area
var/danger_level = 0
// Determine what the highest DL reported by air alarms is
for(var/obj/machinery/alarm/AA in src)
for(var/obj/machinery/alarm/AA in air_alarms)
if((AA.stat & (FORCEDISABLE|NOPOWER|BROKEN)) || AA.shorted || AA.buildstage != 2)
continue
var/reported_danger_level=AA.local_danger_level

View File

@@ -307,13 +307,16 @@ var/global/list/airalarm_presets = list(
if(AC.current == src)
AC.current = null
nanomanager.update_uis(src)
var/area/this_area = get_area(src)
if(src in this_area.air_alarms)
this_area.air_alarms.Remove(src)
..()
/obj/machinery/alarm/proc/first_run()
var/area/this_area = get_area(src)
area_uid = this_area.uid
name = "[this_area.name] Air Alarm"
this_area.air_alarms.Add(src)
// breathable air according to human/Life()
/*
@@ -328,6 +331,13 @@ var/global/list/airalarm_presets = list(
apply_preset(1, 0) // Don't cycle and don't propagate.
apply_mode() //apply mode to scrubbers and vents
/obj/machinery/alarm/Entered(atom/movable/Obj, atom/OldLoc)
var/area/old_area = get_area(OldLoc)
var/area/new_area = get_area(Obj)
if(old_area != new_area)
old_area.air_alarms.Remove(src)
new_area.air_alarms.Add(src)
return ..()
/obj/machinery/alarm/initialize()
add_self_to_holomap()

View File

@@ -146,15 +146,14 @@
door_animate("opening")
playsound(src, soundeffect, 100, 1)
icon_state = "[base_state]open"
sleep(animation_delay)
spawn(animation_delay)
explosion_resistance = 0
setDensity(FALSE)
set_opacity(0) //You can see through open windoors even if the glass is opaque
update_nearby_tiles()
explosion_resistance = 0
setDensity(FALSE)
set_opacity(0) //You can see through open windoors even if the glass is opaque
update_nearby_tiles()
if(operating == 1) //emag again
operating = 0
if(operating == 1) //emag again
operating = 0
return TRUE
/obj/machinery/door/window/close()
@@ -174,11 +173,11 @@
explosion_resistance = initial(explosion_resistance)
update_nearby_tiles()
sleep(animation_delay)
if(window_is_opaque) //you can't see through closed opaque windoors
set_opacity(1)
spawn(animation_delay)
if(window_is_opaque) //you can't see through closed opaque windoors
set_opacity(1)
operating = 0
operating = 0
return TRUE
/obj/machinery/door/window/try_break()

View File

@@ -371,15 +371,17 @@ var/list/map_dimension_cache = list()
/dmm_suite/proc/instance_atom(var/path,var/list/attributes, var/x, var/y, var/z, var/rotate)
if(!path)
return
var/timestart = world.timeofday
var/atom/instance
_preloader.setup(attributes, path)
var/turf/T = locate(x,y,z)
if(ispath(path, /turf)) //Turfs use ChangeTurf
var/turf/oldTurf = locate(x,y,z)
if(path != oldTurf.type)
instance = oldTurf.ChangeTurf(path, allow = 1)
if(path != T.type)
instance = T.ChangeTurf(path, allow = 1)
T = instance
else
instance = new path (locate(x,y,z))//first preloader pass
instance = new path (T)//first preloader pass
// Stolen from shuttlecode but very good to reuse here
if(rotate && instance)
@@ -388,6 +390,9 @@ var/list/map_dimension_cache = list()
if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New()
_preloader.load(instance)
var/timetook2instance = world.timeofday - timestart
if(timetook2instance > 1)
log_debug("Slow atom instance. [instance] ([instance.type]) at [T?.x],[T?.y],[T?.z] took [timetook2instance/10] seconds to instance.")
return instance
//text trimming (both directions) helper proc

View File

@@ -100,16 +100,14 @@
if(AMC.add_shielding(src))
break
if(!mapped) // Prevent suicide if it's part of the map
if(!priorscan)
sleep(20)
controllerscan(1)//Last chance
return
qdel(src)
else
if(!priorscan)
sleep(20)
if(priorscan)
qdel(src)
else
spawn(20)
controllerscan(1)//Last chance
else if(!priorscan)
spawn(20)
controllerscan(1)
return
// Find surrounding unconnected shielding and add them to our controller
/obj/machinery/am_shielding/proc/assimilate()

View File

@@ -144,6 +144,7 @@
var/list/spawned = list()
var/successes = 0
var/list/invalid_bounds = list() // Previously we just removed everything in these bounds from valid_spawn_points, which costed about a second or two during placement, now totally eliminated.
while(map_element_objects.len)
var/datum/map_element/ME = pick(map_element_objects)
@@ -177,7 +178,7 @@
var/turf/t2 = locate(T.x + conflict.width, T.y + conflict.height, T.z) //Corner #2: Old vault's coordinates plus old vault's dimensions
//A rectangle defined by corners #1 and #2 is marked as invalid spawn area
valid_spawn_points.Remove(block(t1, t2))
invalid_bounds[t1] = t2
if(POPULATION_SCARCE)
//This method is much cheaper but results in less accuracy. Bad spawn areas will be removed later - when the new vault is created
@@ -198,7 +199,13 @@
sanity++
new_spawn_point = pick(valid_spawn_points)
valid_spawn_points.Remove(new_spawn_point)
if(filter_function && !call(filter_function)(ME, new_spawn_point))
var/inbounds = FALSE
for(var/turf/start in invalid_bounds) // And begin the invalid bounds checking. Might look like extra work, but is much faster than just removing blocks of spawn points.
var/turf/end = invalid_bounds[start]
if(start && end && new_spawn_point.x >= start.x && new_spawn_point.y >= start.y && new_spawn_point.x <= end.x && new_spawn_point.y <= end.y)
inbounds = TRUE
break
if(inbounds || (filter_function && !call(filter_function)(ME, new_spawn_point)))
new_spawn_point = null
filter_counter++
continue
@@ -215,11 +222,14 @@
if(population_density == POPULATION_SCARCE)
var/turf/t1 = locate(max(1, vault_x - MAX_VAULT_WIDTH - 1), max(1, vault_y - MAX_VAULT_HEIGHT - 1), vault_z)
var/turf/t2 = locate(vault_x + new_width, vault_y + new_height, vault_z)
valid_spawn_points.Remove(block(t1, t2))
invalid_bounds[t1] = t2
var/timestart = world.timeofday
if(ME.load(vault_x, vault_y, vault_z, vault_rotate, overwrites))
var/timetook2load = world.timeofday - timestart
spawned.Add(ME)
message_admins("<span class='info'>Loaded [ME.file_path]: [formatJumpTo(locate(vault_x, vault_y, vault_z))] [(config.disable_vault_rotation || !ME.can_rotate) ? "" : ", rotated by [vault_rotate] degrees"].")
log_debug("Loaded [ME.file_path] in [timetook2load / 10] seconds at ([vault_x],[vault_y],[vault_z])[(config.disable_vault_rotation || !ME.can_rotate) ? "" : ", rotated by [vault_rotate] degrees"].",FALSE)
message_admins("<span class='info'>Loaded [ME.file_path] in [timetook2load / 10] seconds: [formatJumpTo(locate(vault_x, vault_y, vault_z))] [(config.disable_vault_rotation || !ME.can_rotate) ? "" : ", rotated by [vault_rotate] degrees"].</span>")
if(!ME.can_rotate)
message_admins("<span class='info'>[ME.file_path] was not rotated, can_rotate was set to FALSE.</span>")
else if(config.disable_vault_rotation)