Author Topic: LateUpdate eating away performance  (Read 14088 times)

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
LateUpdate eating away performance
« on: October 03, 2013, 02:16:15 AM »
Hey all,

I'm in a pretty far state of my game, built with Toolkit2D and NGUI (and about 10 other plugins, but I think irrelevant). I noticed my game is slow on many of the lower end mobile devices and when I checked with the profiler, I was surprised to see it was the NGUI LateUpdate method which was causing most of the lag. Upgrading to NGUI 3.0 did not help, in fact, it seems even slower.

Anything that comes to mind right away about what I might have done wrong? Or could there be a million reasons? I can get into more detail but I hope there's an obvious answer ;)

I added a screenshot of the profiler, it seems BetterList`1.Add() is making a lot of calls (17532).

Cheers guys


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #1 on: October 03, 2013, 04:10:40 AM »
Deep profile does not give accurate results. Think of it like this... you have FunctionA that takes 100 ms to execute but only gets called once, and then you have FunctionB that takes 0.001 ms to execute, but it gets called 1000 times.

Math gives us:
100 * 1 = 100 ms to execute FunctionA once
0.001 * 1000 = 1 ms to execute FunctionB 1000 times.

Deep Profile adds X time to each function call. For the sake of this example, let's say it's 10 ms. Now suddenly the math becomes:

(100 + 10) * 1 = 110 ms to execute FunctionA
(0.001 + 10) * 1000 = 10,001 ms to execute FunctionB.

See the problem yet?

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #2 on: October 03, 2013, 04:16:44 AM »
Hey ArenMook,

Thanks for the quick response. I see your point. Unfortunately, as usual, this raises more questions.

So you're saying this number of calls from this method should not influence performance (too much)?
Would there be a better way to test this?


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #3 on: October 03, 2013, 04:18:53 AM »
I suggest having a look at what's causing the geometry to be rebuilt frequently, as that's what's ultimately leading to all those BetterList.Add calls. Frequently changing geometry should be moved to its own panel so that it doesn't affect other widgets.

nameles01

  • Guest
Re: LateUpdate eating away performance
« Reply #4 on: October 03, 2013, 04:31:48 AM »
Hello Ivo,

We've gained huge increases in performance by properly using the static flag on UIPanels - this will cause the geometry to stop rebuilding.
We're currently using a tween system for our UIPanels that can toggle the UIPanel to static once it stops tweening.

Of course we only apply this if the UIPanel doesn't have any geometry inside that changes normally.

Also be sure to disable panels once you've tweened them out of screen / they are no longer visibile. This will disable any geometry update and rendering.

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #5 on: October 03, 2013, 04:35:47 AM »
Thanks nameles01 and ArenMook!

I am pretty sure it's because I have about 300 buildings in my screen, all with their own UILabel, but all UILabels are placed in the same panel.

The UILabel is only visible when the building is selected (and moves only when the building is moved) and I guess they should all be in separate UIPanels.

I'll give this a try and let you know if it worked.

nameles01

  • Guest
Re: LateUpdate eating away performance
« Reply #6 on: October 03, 2013, 05:25:54 AM »
I ran a test previously with 2.6.3 and the amount of UIPanels seemed irrelevant. Could've changed of course. Interested in your results.

Edit: I've found that in 3.0.1 the amount of UIPanels used makes a massive difference in performance (fewer=better), when exporting to Flash at least.

Edit2: My results for Flash will conflict yours on mobile - that platform is draw call limited and will always profit from using fewer panels since 1 panel == at least 1 new draw call. Therefore the irrelevancy I noticed in 2.6.3 most likely isn't there for you.
« Last Edit: October 04, 2013, 12:30:04 AM by nameles01 »

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #7 on: October 06, 2013, 09:49:26 PM »
Hey nameles01, ArenMook, others ;)

Thanks for the extra information - a solution that I found was rather simple. Instead of giving each building it's own label, I move the label around based on which building is selected. Simple enough.

However, I also have some labels that are not only visible when the building is selected. They are visible until the building is tapped ("Tap me")-label. There are about 50 of these and like you said, adding multiple UI-panels will dramatically increase drawcalls. Also, just moving around the map will force the geometry to be rebuilt.

Can someone explain to me this rebuilding of geometry? Toolkit2D doesn't seem to have any issue with moving objects (I'd use Toolkit2D for my labels but I need to use a dynamic font). Is there any way around rebuilding geometry every time the labels move? Or can I use something else than a UIPanel - since they all z-sort together and it's all from the same atlas? Or is the dynamic font actually the cause of my problems?

So many questions, would love to get some answers!

Thanks guys

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #8 on: October 06, 2013, 09:54:29 PM »
The widgets don't draw themselves. The panels are responsible for drawing widgets in an efficient, batched fashion. If widgets move, the geometry the panels created becomes invalid and has to be re-created. This is done by re-filling all the affected widgets, which is not a fast thing to do.

Moving panels is quick and efficient because nothing needs to be rebuilt.

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #9 on: October 06, 2013, 09:55:41 PM »
So why does every panel need to be one drawcall? Or doesn't it?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #10 on: October 06, 2013, 09:58:10 PM »
Each panel can be 0 or more draw calls. 0 if it has no widgets, 1 if all widgets use the same atlas, 2+ if not. Panels create draw calls as necessary in order to draw the geometry in the correct fashion (in 3.0).

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #11 on: October 06, 2013, 10:01:14 PM »
So for my problem:

I have 50 widgets in my screen (all from the same atlas)
I want to remove one widget without rebuilding all geometry

There is no options besides having multiple panels which leads to 50 drawcalls, even though the widgets are all from the same atlas with the same z-depth?


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #12 on: October 06, 2013, 10:10:43 PM »
That's right. Best thing to do is to disable components you don't have visible. Are all 50 widgets visible and moving at the same time? If not, disable those that aren't.

ivomarel

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: LateUpdate eating away performance
« Reply #13 on: October 06, 2013, 10:16:59 PM »
Hey ArenMook,

Yes they are all 50 visible at the same time. Does it matter if they are moving? It's only the camera that's moving (zooming/translating - it's an RTS).

If there's no other solution, I might use images instead of text and do this in Toolkit2D.

 


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: LateUpdate eating away performance
« Reply #14 on: October 06, 2013, 10:29:46 PM »
If they aren't moving, turn the 'static' flag on on your UIPanel that draws them.