Updating text each frame causes large allocation spikes

177 views
Skip to first unread message

Dave

unread,
Dec 15, 2016, 5:03:21 PM12/15/16
to Developer Support
Hello,

My team is using HyperText in a large Unity project with Unity's GUI, and we are getting large allocations (around 8.5kb) every 24 frames or so while updating a text field each frame. We do not receive this allocation with the UnityEngine.UI.Text component.

The problem seems to come from two sources: HyperTextProcessor.ProcessInputText(), and HyperText.OnPopulateMesh(). Each one is allocating roughly 4kb during these spikes.

From what I gather, what is happening is that, as the Text.text string is updated, Unity is calling LayoutRebuilder.Rebuild() and Graphic.Rebuild(), and those are eventually leading to the ProcessInputText() and OnPopulateMesh() methods, respectively. If the Text.text property is not updated, these never get called.

I understand HyperText will need to do some calculations as strings are updated, but all we are doing is updating a date and time string in realtime, and need the barest minimum of formatting options (really, just that our style changes are respected, otherwise we would use Unity's Text).

My question is, is there a way to update text but avoid triggering these large allocations? Or any known way we can use HyperText or structure our UI hierarchy that maybe doesn't trigger them?

Thanks,

Dave


Dave

unread,
Dec 15, 2016, 5:27:07 PM12/15/16
to Developer Support



Here is a screenshot from a clean test project using 5.4.3f1 and HyperText 1.8.11. All the scene contains is a canvas and a HyperText object, with this script controlling it:

public class Updater : MonoBehaviour {

    public Text text;

    int counter = 0;

void Update () {

        text.text = (counter++).ToString();
}
}

Once again, using a standard Unity Text component gives no allocations, save for the discarded string.

Developer Support

unread,
Dec 20, 2016, 3:44:35 AM12/20/16
to Developer Support
Thanks for getting in touch about this, Dave! And sorry for the delay.

There are some known issues with updating every frame like this, but I hadn't seen anything quite this dramatic. I just did one quick fix this morning that shaved off about a quarter of heap allocations in my tests, but I'll dig into this more in the coming days. Things will unfortunately be a little slow though just owing to the holidays. I'll post back here when there's an update available.

Dave

unread,
Dec 21, 2016, 9:24:24 AM12/21/16
to Developer Support
Hi, thanks for the quick response. No worries about the holidays, totally understandable. Any improvements you can make would be very welcome, especially on our mobile version, where heap allocations really add up. Thanks again,

Dave

Developer Support

unread,
Dec 22, 2016, 3:31:51 AM12/22/16
to Developer Support
Another quick update. One of the biggest culprits here is actually just copying mesh data, since the existing Unity APIs all allocate new arrays (e.g., Mesh.vertices, Mesh.normals, ...).

I managed to add some non-allocating API points for these last night (Mesh.GetVertices (), Mesh.GetNormals (), ...). I expect I can get these into Unity 5.6.0 during some beta in the new year, and I will see if I can get them back-ported as well.

Developer Support

unread,
Jan 22, 2017, 2:15:55 PM1/22/17
to Developer Support
Just a quick update: I managed to get the necessary updates approved for 5.6.0b5 and 5.5.1p1. Not sure yet if I'll be able to get them into 5.4.x or 5.3.x, so I wouldn't count on it, but I'll make sure HyperText is updated properly to account for these new non-allocating Mesh APIs for 5.6.0f1 and 5.5.2f1.

Developer Support

unread,
Feb 1, 2017, 5:02:51 AM2/1/17
to Developer Support
Hi again! HyperText 1.8.12 is available for download today, which has fixed this problem. Thanks again for getting in touch about it. The release note of interest is:

  • Eliminated heap allocations when continuously updating basic text; substantially reduced allocations when using features like links and keyword detection. This change affects Unity 5.5.2 and newer (including 5.6.0 beta), as well as Unity 5.4.x from 5.4.5 onward.

Dave

unread,
Feb 2, 2017, 11:02:08 PM2/2/17
to Developer Support
Hey, thanks for looking into this! I look forward to trying this out after we update our project to Unity 5.5, within the next few weeks. 

Dave
Reply all
Reply to author
Forward
0 new messages