Graf Zahl wrote:Oh my, this mod is creating roughly 4000(!!!) layout objects per frame! It occasionally skips a frame but that only seem to be frame drops where the HUD is not being rendered for a tick.
It seems to create a huge OOP-based layout hierarchy and instead of caching it recreates it EACH! SINGLE! TIME! it gets rendered.
I'm sure if this was Java it would start to choke under the constant GC stress as well. It's simply not how a garbage collected language can be used. They occasionally need some time to take down all the trash, but here it continues with this insanity while the GC helplessly tries to catch up, never managing.
TBH, code like this is what gives OOP a bad name.
This code is so extremely scattered into micro-methods that I have no clue where even to look for a start of this all.
I'm sorry, but in this case my only response is "Fix the mod!"
There has to be some means to detect whether the most recent layout is still valid or not so that it won't have to be recreated over and over and over again in its entirety.
Most of the objects that get created are immutable and they should probably use a cached pool of some sort, although I'm not sure how difficult it might be to implement that in ZScript, if at all possible. Let's start with no static variables (although it could probably be done with StaticEventHandler, provided that UI code can access it) and no generic dictionaries (only string->string), or, for that matter, no generic types at all. This should probably be done on the engine side, although I guess it'd likely be too much to ask for a rather niche use case.
However, there might be a way to optimize the code somewhat. That's in fact what I've been working on after reporting the struct-related crash, and it does involve detecting layout changes. The problem, is, however, that traversing the layout tree and asking each leaf node if anything has changed still involves calculations of some sort (to compare the results with the cached ones) and produces more wrapper objects. I cannot get rid of them all entirely - their sole purpose is convenience; the code would be a lot more difficult to read and maintain otherwise. Granted, however, the total number of objects in this case
might be less, but I'm yet to get to the testing phase so I can't tell what the actual difference is going to be.
Also, I did not receive any email notifications after my last reply, so I'm sorry for not replying earlier.