question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unity heavy GC allocation on Render

See original GitHub issue

Question

I’am try to loading just 4kb .gp5 file, which results in output .png 96kb. My setup var settings = new Settings(); settings.Core.Engine = "skia"; settings.Core.LogLevel = LogLevel.None; Score score = ScoreLoader.LoadScoreFromBytes(Encoding.ASCII.GetBytes(testTab), settings);

LoadScoreFromBytes() https://i.imgur.com/LObmSWy.png As you can see, logger was not deactivated + additional GC

RenderTracks() https://i.imgur.com/NXIGgti.png 2mb GC.

1)Does it possible to disable logging at all? 2)Does it possible to reduce GC allocation? 3)Does it possible to run this in the separate thread? Seems, yes. 4)Does it possible to omit description(name, tuning, bpm) in rendered file?

Your environment (if applicable)

  • Version used: .net master
  • Platform used: Unity 2019.2, C#
  • Rendering engine used: SVG
  • Operating System and version (desktop or mobile): Windows 10

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
Danielku15commented, May 14, 2020

Sorry, my bad with providing the wrong the namespace.

AlphaTab with all libraries: alphatab, SkiaSharp, libSkiaSharp is about 12mb. But min.js version of AlphaTab is only 1mb. May be it’s somehow possible to reduce size for C#?

Lets dissect this number to clarify where these sizes come from.

The main DLL of alphaTab is 4.48MB. This includes the alphaTab code a 3.31MB soundfont and a 632KB TTF Font for the symbols. So the actual code of alphaTab takes up 0.54MB. So the .net version of alphaTab takes 0.54MB while the minimized JS version needs 1.07MB. The JS version still loads the SoundFont and WebFont into the memory of the browser making the JS version 0.5MB less efficient than the .net version.

So let’s talk about possible optimizations:

alphaTab DLL The TTF font is mandatory to do any kind of rendering so the minimum of the alphaTab core library is still 1.16MB. I can take it up for the upcoming TypeScript based version to move the SoundFont from the core library to the windows specific control library. Giving you 1.16MB for alphaTab.

alphaTab is currently not using all glyphs from the font, so theoretically we could try to minimize the font to only contain the symbols used making an alphaTab optimized Bravura font. There are 3227 glyphs in the font and alphaTab is using 93 of them😅. Assuming an equal number of KB per symbol, the font could be shrinked to 18KB (20KB more realisticly). This would result in 0.54MB for the core library. Feel free to open a dedicated feature request for this optimization.

SkiaSharp

You are using Unity, and Unity does not provide any built-in mechanism to render images so it must rely on a 3rd party library to do this Job.

You can ask over at the SkiaSharp repo if there are better ways to minimize the size of the library but we do not have much control over that: https://github.com/mono/SkiaSharp

If you find a more lightweight library for rendering images on Unity, feel free to open a feature request to provide a rendering backend for it.

Does it possible to get byte[] or Color[] from SKSurface? I want to use it in UI like Sprite.

This is more a question to SkiaSharp and the documentation there. In general: yes it is possible to get the raw bytes and raw pixel colors.

1reaction
Danielku15commented, May 7, 2020

You have to consider that having a final PNG encoded has a lot of raw image processing inbetween. This raw image processing is done on Bitmap base and will need corresponding memory.

1)Does it possible to disable logging at all?

As you’re using the low level APIs you will need to set Logger.LogLevel instead the setting on the main settings object. Normally the API object takes over the responsibility to initialize the internal logger.

Even though the log level is part of the settings object, it is actually still a global setting within alphaTab and not “per-call”.

Still it is quite surprising that the memory allocation is supposed to be so heavy there. Can you see on the deeper nodes of the memory trace what exactly is causing these allocates?

2)Does it possible to reduce GC allocation?

What do you mean by “GC allocation”? alphaTab needs to create an object graph for the data model and the rendering tree. There is no way of reducing the memory actually needed for this operation. In your case where you are maybe just doing a one time PNG conversion this might be an overhead but normally alphaTab is more long-lived as control. You might use the score model to also fill some other UI elements. The rendering pipeline is reusable for resizing of the UI.

If you convert a Score to PNG and scrap the whole objects the GC will simply need to cleanup all of this. Every symbol alphaTab renders is an object to reposition and re-render it in case of resizing.

3)Does it possible to run this in the separate thread? Seems, yes.

Yes it is possible. The normal UI controls already off-load the whole rendering process to a background thread. As you are using the ScoreRenderer directly you will need to move it to a thread on your own which should be easily possible. Once alphaTab completes the rendering and hands over the final SkImage it will not access this image anymore. No need for thread synchronization on this object.

4)Does it possible to omit description(name, tuning, bpm) in rendered file?

This is documented here: https://docs.alphatab.net/develop/reference/property/

Read more comments on GitHub >

github_iconTop Results From Across the Web

Garbage collection best practices - Unity - Manual
This section outlines some common issues and workflows that affect when your application triggers the garbage collector. Temporary allocations; Reusable object ...
Read more >
Unity Profiler doesnt show where the GC allocations are ...
When I look at the memory overview, it says that GC allocations per frame are as low as 300 and as high as...
Read more >
Basics of Optimization in Unity - Ali Emre Onur - Medium
Let's initialize a color variable with new keyword and run the Unity Profiler to observe the allocated space on the GC.
Read more >
Unity Tips | Part 1 - Garbage Collection - Daniel Ilett
As you've probably worked out, Instantiate allocates memory resources to bring the object into the game and Destroy removes them from memory – ......
Read more >
Slow rendering - Android Developers
If your app suffers from slow UI rendering, then the system is forced ... of allocation can mean more CPU resources spent on...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found