Skip to content

Conversation

@Phantomical
Copy link

@Phantomical Phantomical commented Oct 23, 2025

This calls UnityEngine.Object.GetObjectsOfType which is terribly slow. It is not used anywhere in stock which is probably why it hasn't been patched yet. However, several mods do make use of it.

On my KSP instance this saves > 1s on every scene switch across a few different mods.

The improvement here is to maintain our own list of active UIPartActionWindow instances and use that list instead of calling GetObjectsOfType. It proactively removes all dead instances when one is deleted. Any change that results in UIPartActionWindow.OnDestroy not being called will result in a memory leak anyways so I suspect this is a non-issue.

This calls `UnityEngine.Object.GetObjectsOfType` which is terribly slow.
It is not used anywhere in stock which is probably why it hasn't been
patched yet. However, several mods do make use of it.

On my KSP instance this saves > 1s on every scene switch across a few
different mods.

The improvement here is to maintain our own list of active
UIPartActionWindow instances and use that list instead of calling
`GetObjectsOfType`. It proactively removes all dead instances when one
is deleted. Any change that results in `UIPartActionWindow.OnDestroy`
not being called will result in a memory leak anyways so I suspect this
is a non-issue.
@gotmachine
Copy link
Contributor

gotmachine commented Oct 23, 2025

KSP already maintain a list of all instantiated PAWs in UIPartActionController.windows, there is no need to duplicate it.

But as a matter of fact, there is an even simpler and faster way :

static void MonoUtilities_RefreshContextWindows_Override(Part part)
{
    if (part.IsNotNullRef() && part.PartActionWindow.IsNotNullOrDestroyed())
        part.PartActionWindow.displayDirty = true;
}

Also, given the scope of the patch, this should likely go into the existing MinorPerfTweaks patch instead of having a whole dedicated entry.

@Phantomical
Copy link
Author

I'm happy to change up the patch here. Is it ever possible for there to be more than one PartActionWindow for the same part?

Would it also make sense to change RefreshPartContextWindow to do the same here then? It is not nearly as bad but UIPartActionController.Instance.GetItem iterates over all the listed part action windows.

@gotmachine
Copy link
Contributor

Pretty sure there can only be single PAW per part.

Yeah, it would make sense to use the same implementation for MonoUtilities.RefreshPartContextWindow() as well.

Those MonoUtilities methods are pretty ancient and predate the addition of the Part.PartActionWindow property, I think it was introduced sometimes between KSP 1.5 and 1.8.

@Phantomical
Copy link
Author

This should be good to go now. I've done some basic testing and everything seems to still work properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants