Huge perf hit in editor with very large array properties

So I am dealing with an issue here with BP Actors that have variable arrays that have many thousands of items. If this variable is marked as “Editable” so that it shows up in the properties panel, then performance takes a huge hit. Make the variable not “Editable” and performance goes back to normal. After some digging through stats it appears as though the problem is in Slate. Specifically the “DrawWindows” under the Slate STAT jumps up to very high times. Now my guess is that this is time spent drawing out all the UI controls for the very large array. However this performance hit is there even if the control is “collapsed”, and even if the parent control is collapsed, therefore the variable isn’t even visible. My guess is slate is computing and drawing this even when it isn’t necessary.

As an example, I have an Actor Blueprint with an array variable that is 10,514 elements long at present. Each element in the array is a struct that has one element.

Variable marked as editable, Actor selected in World Outliner so that properties are visible: Slate->DrawWindows ~25ms. This value does not change as long as the properties are visible. Even if the specific variable is collapsed, or expanded, and even if the group that it is in is collapsed, the value remains constant. As long as that actor is selected so that its properties are loaded into the details panel, that time will be consistent.

Now deselect the actor so that the properties are not loaded: Slate->DrawWindows ~4.5ms

Actor selected so its properties are visible, but the variable NOT Marked as editable and therefore does not show in properties: Slate->DrawWindows ~10ms. Higher than being completely deselected, but there are other variables in the actor including a few smaller arrays that are no doubt still dragging somewhat.

Hello,

I have a few questions for you that will help narrow down what issue it is that you are experiencing.

Quick questions:

  1. Can you reproduce this issue in a clean project?
  2. If so, could you provide a detailed list of steps to reproduce this issue on our end?
  3. Could you provide screen shots of any blueprints that are involved with this issue?
  4. Is there a minimum number of elements needs to reproduce this issue or does performance gradually reduce as you approach 10k+ elements?

Can you reproduce this issue in a clean project?

Yes.

If so, could you provide a detailed list of steps to reproduce this issue on our end?

Important Note: Drawing Tooltips seems to be a large strain on Slate as well, and will skew your numbers. At all time sin this test when recording numbers, ensure the mouse is not over any UI element and that no tooltip is being drawn.

  1. Start a new project in 4.8 using the FPS template, though any template should be fine.
  2. Once loaded, create a Blueprint Structure, named whatever
  3. In that structure add around 5 member variables. Type doesn’t matter, though in my tests using Transforms will cause the most slowdown (I’ll cover why after)
  4. Make a new Blueprint based on Actor, named whatever
  5. In the Actor Blueprint add a member variable that is an array of the struct you created in step 2. Make that struct Editable so that it shows up in the properties panel in the World Outliner
  6. In the Blueprint’s construction script, simply make a very small script that ADDs two or three elements onto the end of the array when run. This is just to give you an easy way to progressively increase the array size. It is quicker than clicking plus over and over :smiley:
  7. Save and compile your blueprint
  8. In the world, drag in a copy of this new blueprint actor and ensure you do see the array variable in the properties. Do not expand it.
  9. In the 3d view, click the Down Arrow in the top left of the viewport to open the menu and select Stat->Advanced->Slate. Once you do that the stats should display but if they don’t then select Show Stats from the top level of that same menu
  10. You should now see the Slate stats. The one we are concerned with is “DrawWindows” which should be the second row in the first section. The specific numbers will vary greatly depending on the machine being used, but note what it is at the start, probably somewhere around ~2-5ms
  11. Now select the blueprint actor in the world, go into translate mode, and just start dragging it around. As you do the size of the array should be increasing rapidly. Keep doing so until the size of the array is ~1,000 entries.
  12. Stop dragging, stop interacting with the UI in any way. Make sure the mouse isn’t over say a tooltip of anything (as that affects the numbers). Note the time required on the DrawWindows now. It will be longer.
  13. Repeat steps 11 and 12 progressively through 2, 3, 4, 5k etc. Each time note how it gets longer and longer to DrawWindows
  14. Once the array size is quite high, say 5-10k you should notice the DrawWindows being noticeably higher than at the start. Also note how the time spent on DrawWindows while dragging the actor is also shooting pu into very high values the larger the array gets.
  15. Note also that this test is done with the array control collapsed, as it is by default, so you Slate is essentially spending time drawing controls that are not visible. This can be further driven home by collapsing the “Default” group in the properties, so now even the top level array control is not visible, yet the time spent on DrawWindows will be virtually unchanged. Last expand both the Default group AND the array variable so that you can see the entries, and note that again DrawWindows is barely affected.
  16. Select a different actor in the scene so that the properties panel changes to display a new actor. Note how the DrawWindows time is reduced.

Could you provide screen shots of any blueprints that are involved with this issue?

Unfortunately due to MPAA restrictions I am unable to post screenshots of anything (The computers are not connected to the internet), but the above instructions should be sufficient

Is there a minimum number of elements needs to reproduce this issue or does performance gradually reduce as you approach 10k+ elements?

It really depends on several factors including the performance of the machine, and the composition of the array, but if you pay attention to the Slate->DrawWindows stat you can see the time spent there getting longer and longer gradually as the arrow grows.

One thing I did notice in setting up this test is that it appears that, for lack of a better description, the UI tree levels are what most directly affect the performance. By that I mean the number of nested UI elements that can be expanded and collapsed with the twiddle arrow. This can best be seen by doing the above test with a struct composed of 5 member variables of a simple type like Bool. Then one you have 3 or 4 thousand entries, and you have some numbers recorded, change the struct’s members to be a complex type like Transform. Because this is a more complex type, each array element in the UI sense goes form a single twiddle arrow to multiple. On my work machine this change from Bool to Transform, with ~2,500 elements, caused DrawWindows to go from ~15ms to ~190ms

Due to the length of my response, I am unable to post it as a comment (it exceeds the character count limit) so I am posting it as an answer.

One thing I would like to note on this is despite my problems with very large arrays, this is really more fundamental than that. The underlying issue is Slate wasting time drawing/processing UI controls that are not visible. fixing this would not only fix my specific problem but would probably result in the editor overall getting faster and more responsive/snappy.

Hello,

I was able to reproduce this issue on our end. I have written up a report (UE-20224) and I have submitted it to the developers for further consideration. I will provide updates with any pertinent information as it becomes available. Thank you for your information and time.

Make it a great day

I was wondering if I could check the status of this issue? It is one of our top hot button issues.

Thanks!

Hello,

I went ahead and double checked on this issue for you and it appears that this issue’s status has not yet been updated to fixed. However, I will be sure to bump up the community interest for you.

Thanks Rudy. I have to say that is certainly disappointing considering here we are 3 major versions later but I understand. It is definitely a huge problem for us so I guess we will have to try and find a way to fix it ourselves.

As an aside please consider that this is something that would have HUGE performance benefits throughout the editor for everyone. While the problem becomes mkost apparent with the situation I described, the fact remains that the underlying issue of Slate time being wasted on invisible controls would surely trickle out into some pretty major benefits if fixed.

Want to check on this again. This continues to be probably our largest problem with UE4 in our workflow, and here we are now many many versions later still dealing with the same problem. Is there any chance this has been looked at at all for 4.15? This isn’t exactly and edge case situation, and can easily be seen by any artist for example using HISMs to generate large numbers of instances. Just selecting the HISM with a few thousand instances can freeze the editor for a minute, and then the UI time spent drawing all those controls that aren’t even visible has a significant impact on frame time.

Getting Slate to not waste cycles drawing hidden UI elements would be a huge win for everyone in terms of editor performance.

I have provided a link to the public tracker. Please feel free to use the link provided for future updates.

Link: Unreal Engine Issues and Bug Tracker (UE-20224)

Make it a great day

Developer Notes
This issue has been closed as ‘Won’t Fix’ due to an extended period of time without updates. If this issue is important to you please let us know by posting on the AnswerHub or UDN, and Epic will re-open the ticket for further review.

So wait I’m confused. This whole time issue had been closed because I wasn’t bothering you about it?

Hello,

That message was out of date, the issue was reopened after renewed interest. This issue was only recently closed as won’t fix. In cases like these, when that message is attached to a won’t fix, all you need to do is reply to the original posting to let the developers know that there is still a need/interest in the issue (this typically only happens to really old issues). I hope this helps clear things up.

This is still an issue with 4.25. It would be nice if it’s gonna be fixed.