You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here is the overview of the API-controlled DotTrace profiling of a flight <> flight scene transition, from the scene switch request to the fifth fixedupdate after the scene has been loaded, which is roughly the point at which the game becomes responsive again. I'm reloading the same 450 parts stock vessel :
The whole operation took 16 seconds. In the rough orders of events :
27.8% (4.8s) is spent cleaning up and destroying the scene objects. Out of that, 80% (3.8s) of the time is spent doing some Unity/PhysX internal operation to (seemingly) reset/cleanup the colliders ignores state. I haven't verified how much time would be spent if no ignore pairs are set, but this would likely eliminate the whole operation. As a reminder, colliders ignores pairs are set by KSP between each loaded part to provide the "ignore vessel self collisions" feature. The amount of pairs is the amount of parts squared, so this is something that scale very badly with part count.
5.8% (1s) is spent collecting and unloading assets. Note that the KSPCF ForceSyncSceneSwitch patch was active, this operation would have taken significantly more time otherwise.
2.6% (0.4s) is spent in various KSP scene switch logic and events, and roughly half of that is in parsing the save file (note that in "usual" scene switches, this step is skipped thanks to the SceneLoadSpeedBoost KSPCF patch, but I was triggering things manually).
9.2% (1.5s) is spent instantiating the vessel, its parts and modules. Roughly 1/3 of that time sent in various scattered operations, 1/3 in actual instantiation of unity objects, 1/3 in parts/modules Awake(), most of that being KSP putting together the Parts/Modules Basefield/event/action scaffolding in ModularSetup().
11.7% (1.8s) is spent in Parts/Modules Start()/OnStart()/OnStartFinished() code. Things here will be vastly dependent on which modules are present, but in my test case, "core" part setup was about 28% of the operations, the rest being code owned by modules.
11.1% (1.8s) is spent setting up the part collision ignore pairs from CollisionManager.FixedUpdate(), and this is the aready optimized version from the CollisionManager performance when new vessels are created. #174 patch. Note that 96% of the time is in the Unity native IgnoreCollision() method, which is called (part count)^2 times.
5.2% (0.8s) is spent in creating the temperature overlay gauges. This overhead should be vastly reduced if not totally eliminated by the (not yet merged as of writing) Faster implementation of TemperatureGaugeSystem #270 PR.
The rest, about 10%, is in various small scattered operations, mainly internal code from Unity and a few KSP subsystems.
As a quick comparison, the same operation but with a 1 part vessel is taking 3.9 seconds.
The main operations are :
Collecting and unloading assets : 0.5s (1s in the 450 parts test case)
SetPQSActive() : 2.5s (no change)
The main thing that stand out is the cost of cleaning and setting up collision ignores. Overall, about 6 seconds out of 16 are directly caused by that (note that this account for the additional collision ignores defined by struts/compound parts, my test case had a bunch of them).
While there isn't much (more) we can do about the setup part, it might be interesting to see what happens if we reset all collision ignores manually prior to leaving the scene. The operation would be roughly identical as setting them up, so it would theoretically take about 1.8s, compared to the automatic cleanup done by Unity taking 3.8s, so it could be a nice improvement, but this assume it would eliminate all related operations done by Unity automatically, which is far from granted. This need to be prototyped to validate what would actually happen.
Other than that, there isn't much standing out.
Parts/Modules Awake() and ModularSetup() could likely be optimized a little bit, but not enough to make a visible difference. We are talking at maybe shaving 100ms out of 400, although that could start to matter a bit more in modded games where the average modules per part ratio is often much higher.
One interesting takeaway is that persistent data deserialization (ie, persistent KSPFields, OnLoad() partmodule overrides and persistent part data) is taking about 120ms, so while the de-serialization code is far from efficient, in practice this is a non-issue.
In the end, the main potential optimizations are in the setup code of individual PartModules (~12%, 1.8s). Stock modules are relatively decent on that front, at least not too many of them are doing really stupid stuff. There are still a few cases that could be made better, ModuleCargoBay and ModuleProceduralFairings are standing out as notable offenders in my test case (but it has maybe 16 of them, so not a very typical setup...). Struts / compound parts are also not great, but I'm not sure there is much to done here. Profiling different types of vessels and situations would be needed to identify potential improvements.
Also do note that my profiling was in sandbox, there might be additional overhead in career.
And on a final note, while the stock scene switch times aren't great, they are still relative acceptable. From my experience, the real issues and optimization opportunities are in mods, many of them are doing their setup/initialization in awfully inefficient ways. A very notable offender is B9PartSwitch, which has become a backbone of the modding ecosystem. There are trivial changes that would make huge improvements there.
The text was updated successfully, but these errors were encountered:
Here is the overview of the API-controlled DotTrace profiling of a flight <> flight scene transition, from the scene switch request to the fifth fixedupdate after the scene has been loaded, which is roughly the point at which the game becomes responsive again. I'm reloading the same 450 parts stock vessel :
The whole operation took 16 seconds. In the rough orders of events :
ForceSyncSceneSwitch
patch was active, this operation would have taken significantly more time otherwise.SceneLoadSpeedBoost
KSPCF patch, but I was triggering things manually).Awake()
, most of that being KSP putting together the Parts/Modules Basefield/event/action scaffolding inModularSetup()
.SetPQSActive()
. Detailed breakdown of that is covered in Investigate PQS performance #271.Start()
/OnStart()/OnStartFinished()
code. Things here will be vastly dependent on which modules are present, but in my test case, "core" part setup was about 28% of the operations, the rest being code owned by modules.CollisionManager.FixedUpdate()
, and this is the aready optimized version from the CollisionManager performance when new vessels are created. #174 patch. Note that 96% of the time is in the Unity nativeIgnoreCollision()
method, which is called (part count)^2 times.TemperatureGaugeSystem
#270 PR.As a quick comparison, the same operation but with a 1 part vessel is taking 3.9 seconds.
The main operations are :
SetPQSActive()
: 2.5s (no change)The main thing that stand out is the cost of cleaning and setting up collision ignores. Overall, about 6 seconds out of 16 are directly caused by that (note that this account for the additional collision ignores defined by struts/compound parts, my test case had a bunch of them).
While there isn't much (more) we can do about the setup part, it might be interesting to see what happens if we reset all collision ignores manually prior to leaving the scene. The operation would be roughly identical as setting them up, so it would theoretically take about 1.8s, compared to the automatic cleanup done by Unity taking 3.8s, so it could be a nice improvement, but this assume it would eliminate all related operations done by Unity automatically, which is far from granted. This need to be prototyped to validate what would actually happen.
Other than that, there isn't much standing out.
Parts/Modules Awake() and ModularSetup() could likely be optimized a little bit, but not enough to make a visible difference. We are talking at maybe shaving 100ms out of 400, although that could start to matter a bit more in modded games where the average modules per part ratio is often much higher.
One interesting takeaway is that persistent data deserialization (ie, persistent KSPFields,
OnLoad()
partmodule overrides and persistent part data) is taking about 120ms, so while the de-serialization code is far from efficient, in practice this is a non-issue.In the end, the main potential optimizations are in the setup code of individual PartModules (~12%, 1.8s). Stock modules are relatively decent on that front, at least not too many of them are doing really stupid stuff. There are still a few cases that could be made better,
ModuleCargoBay
andModuleProceduralFairings
are standing out as notable offenders in my test case (but it has maybe 16 of them, so not a very typical setup...). Struts / compound parts are also not great, but I'm not sure there is much to done here. Profiling different types of vessels and situations would be needed to identify potential improvements.Also do note that my profiling was in sandbox, there might be additional overhead in career.
And on a final note, while the stock scene switch times aren't great, they are still relative acceptable. From my experience, the real issues and optimization opportunities are in mods, many of them are doing their setup/initialization in awfully inefficient ways. A very notable offender is B9PartSwitch, which has become a backbone of the modding ecosystem. There are trivial changes that would make huge improvements there.
The text was updated successfully, but these errors were encountered: