Author Topic: UIInput caret causes GC spikes  (Read 1852 times)

Zylann

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 17
    • View Profile
UIInput caret causes GC spikes
« on: September 07, 2016, 11:23:26 AM »
I found that when a text box is selected, there is a big purple spike in "GC Allocated" lane of the profiler everytime the caret blinks.
It also produces huge GC spikes after some time (up to 50ms in my project), which don't appear at all when the text box is not focused.

I tested this in the NGUI chat example, and I clearly saw the spikes when the text box is selected, then they disappeared after deselecting it.

Are you aware of this? Is there a way to fix it?

Edit:
I found out it's because of this in UIDrawCall, when a panel gets rebuilt:
  1.                     mMesh.vertices = verts.ToArray();
  2.                     mMesh.uv = uvs.ToArray();
  3.                     mMesh.colors = cols.ToArray();

ToArray requires to put an array of the correct length, so the internal buffer of BetterList is shrunk to fit the actual size, not capacity, causing tons of GC, because:
  1.             if (size < buffer.Length)
  2.             {
  3.                 T[] newList = new T[size];
  4.                 for (int i = 0; i < size; ++i) newList[i] = buffer[i];
  5.                 buffer = newList;
  6.             }

A way to avoid this would be to use the new SetVertices(List<Vector3>) but since BetterList is used everywhere in NGUI it's a lot of work.

Did anyone thought about this already?
« Last Edit: September 08, 2016, 06:29:10 AM by Zylann »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIInput caret causes GC spikes
« Reply #1 on: September 09, 2016, 02:17:20 PM »
The caret is a visible widget. In order to make it blink, draw calls need to be updated. Draw calls update affects everything in the panel. The more widgets you have in your panel that has the input field, the greater the cost.

Unity 5's support of List may be a good case to switch NGUI away from BetterList, assuming it actually is more than a convenience on Unity's end. Did you test to see if it actually helps? For all you know, Unity just does a ToArray() conversion internally.

Zylann

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 17
    • View Profile
Re: UIInput caret causes GC spikes
« Reply #2 on: September 10, 2016, 08:38:53 AM »
I understand this affects the panel and causes geometry to be rebuilt. I was just not expecting that much allocations, knowing NGUI tries to optimize its resources usage, from what I've seen so far in the code.

I made a quick test project where a script generates a bunch of vertex-count-changing quads in a mesh every frame by using the List API.
Although I see the "total GC allocated" doing ramps even when no script is active, I didn't see any allocation on my side except the occasional ones done by the editor.



I didn't tried that on NGUI directly because I don't have the source code right now (I'm at home).