Search Unity

TextMesh Pro Huge GC Alloc by assigning text

Discussion in 'UGUI & TextMesh Pro' started by AQAGA, Dec 6, 2020.

  1. AQAGA

    AQAGA

    Joined:
    Jan 11, 2020
    Posts:
    25
    First of all, I would like to thank you for this awesome tool, and the support you are providing. Unfortunately, I have stumbled upon an issue, I can't resolve using the already given answers.

    Versions:
    Unity 2019.4.16f1
    TMP 2.1.3

    If I assign a text at runtime, that is about 100 characters long (and with rich tags (font, color, size) it would be about double that), I get huge spikes in the profiler after I press the spacebar.

    Code (CSharp):
    1.     [SerializeField] string textToTest;
    2.  
    3.     TMP_Text text;
    4.     void Awake() => text = GetComponent<TMP_Text>();
    5.     void Update()
    6.     {
    7.         if (Input.GetKeyDown(KeyCode.Space))
    8.             text.text = textToTest;
    9.     }
    10.  
    Here I have pressed the spacebar.
    tmp input text.png
    Here I have manually cleared in the TMP component the inputted text
    tmp text removed.png
    And here I have pressed the spacebar again
    tmp inputed text again.png


    What am I trying to achieve? I want to assign different prewritten text (with no concatenation and so on) to the same textbox at runtime once I press a specific button.
    I assumed that simply using .text would do it, but is there perhaps some other way of achieving 0 GC text assigning in my situation?
     
  2. AQAGA

    AQAGA

    Joined:
    Jan 11, 2020
    Posts:
    25
    I profiled on a standalone build with the same result.
    I also noticed, that if I reassign the same text into the same field, I get about 10% of that Garbage.
    So it has something to do with some sort of resizing.
     
  3. AQAGA

    AQAGA

    Joined:
    Jan 11, 2020
    Posts:
    25
    Update:
    I am also getting garbage without using rich tags, just a bit less. Less perhaps due to the fact, that less text is actually being assigned.
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    When the text object is awaken and text is first assigned to it, some allocations will occur to allocate the relevant buffers for text processing and geometry.

    Subsequent changes to the text provide the text doesn't change length by more than a factor of 2 will not result in further allocations.

    Are you seeing these allocations on first invocation or on subsequent assignment?
     
  5. AQAGA

    AQAGA

    Joined:
    Jan 11, 2020
    Posts:
    25
    I have 0b allocation later on. This happens only once. In fact, I have almost the same result with the standard Unity text solution. But still. I won't be having just one text box to fill. And having 500.000b worth of garbage every time the box gets filled once seems to be just unacceptable. Was it always like that? I even tried the latest 2020 version with the same result.
    Is there a way to allocate the relevant buffers on level start rather than during gameplay?
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    These allocations will occur when the text object is first created and text assigned to it which can occur as a scene is loaded that contains text objects or if you have a logic that instantiates those object when loading your levels.

    Once the object has been created, no further allocations will occur unless the text grows in size as per my previous post.

    These allocations will remain for the life of the text object.

    The size of the allocations is relative to the amount of text contained in the text object.

    Make sure you are using the latest release of the TMP package which includes some reduction in memory overhead as some of the data structures used in the parsing and layout of the text is shared between objects.