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.

SVG Pins: performance issues

See original GitHub issue

I suspect that the memory handling for SVG Pins is not quite optimal, and might have some issues.

Let me illustrate this with the following scenario:

  • I have a map based on Mapsui.UI.Forms.MapView with a potentially larger number of pins.
  • There are a number of different types of pins, where each type has its own image (e.g. given by an svg or png file). Let’s say we have something like 10-20 types, and each image file has a few kB.
  • The map will contain many pins of each type (say: hundreds or thousands).

Since there are many pins, I’d like to avoid duplicating the memory allocated for their images, for reasons of performance and memory footprint. I can see some potential issues in this direction (I’ve been looking at the Pin class and Pin.CreateFeature in particular):

  1. For svg pins, the svg data is stored as a string (Pin.Svg). In Pin.CreateFeature this is then converted (copied) into a byte array via Encoding.UTF8.GetBytes. This means that for every Pin object I create, I make a separate copy of my svg data, right? For small svgs this might not be a problem, for for more complex ones that have several kB in size, it adds up. And it seems to be avoidable by making Pin.Svg a byte array (just like Pin.Icon) instead of a string. Correct?

  2. IIUC the BitmapRegistry class could be used to avoid duplication of image data, but it seems to me that for every new pin a new entry in the BitmapRegistry is generated (since Pin.CreateFeature alwas seems to call BitmapRegistry.Instance.Register). Is that right, or have I simply not looked deep enough into the code? For png pins it might not be a problem: We might have multiple registry entries, but ultimately they all point to the same data in memory. But for svg (since we make a copy along the way, see first point above), we have multiple entries and they all point to their own private copy of the data, right?

@pauldendulk @charlenni I’d be grateful for any kinds of comments on this. Am I missing something here?

Issue Analytics

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

github_iconTop GitHub Comments

1reaction
tmijieuxcommented, Mar 14, 2021
if (redraw)
{
    dt = _stopWatch.Elapsed.TotalMilliseconds;
    Invalidate();
    Debug.WriteLine($"Last draw needs {(_stopWatch.Elapsed.TotalMilliseconds-dt).ToString("N3", CultureInfo.InvariantCulture)} ms");
}

The drawing is not necessarily done synchronously during the InvalidateSurface() call, the draw may not even be done on the UI thread, if you want to measure the duration of a draw you must time at the beginning and the ending of the PaintSurface event handler. (I suggest that we measure the drawing of each layer independently, we may have unexpected surprises)

Look at this test project I made, the actual number of draws is not equal to the number of call of InvalidateSurface() and (at least on my phone) the PaintSurface is not called on the main thread at all, and the PaintSurface method may be called after InvalidateSurface returns ( the conditions when this happens in that particular project may be biased because my PaintSurface is doing almost nothing except clearing the screen and drawing a simple circle)

also the documentation clearly states that invalidateSurface must be called on UI thread

https://docs.microsoft.com/en-us/dotnet/api/skiasharp.views.forms.skcanvasview.invalidatesurface?view=skiasharp-views-forms-2.80.2 This needs to be called from the main thread.

EDIT: the reason of this behaviour is probably the following (rough guess) The main loop on the main threads probably does something like

while (true)
{
    1. Poll for events and timers
    2. execute Events And Timers Callbacks() ("user" code)
    3. Check if user code invalidated some view and redraw if needed
}

when a view is updated during user code the propertychanged registered by the xamarin framework itself will call some method to invalidate the view (something like requestLayout()) The implementation of that method(once again this is guess for now, i did not looked at the code yet) starts a short timer (few milliseconds) (if not started yet). When the timer ends, drawing is done. If the timer is already started and finishes during user code and requestLayout() is called, then a draw is done immediately, (during user code)

I think that explains rather well the behavior i see

0reactions
januswcommented, Jun 10, 2022

This can be closed. Most of the performance issues described above were basically fixed for me with #1192.

Read more comments on GitHub >

github_iconTop Results From Across the Web

From SVG to Canvas – part 1: making Felt faster
In this post, we're going to explain: the problems we faced with SVG rendering; how we went about the switchover; some of the...
Read more >
Optmizing SVG performance for mobile device and Safari ...
Hey folks, I have created this animation usign ScrollTrigger which work perfectly fine, but I am having trouble making its performance ...
Read more >
rendering network SVG images causes performance ...
Agree. SVG image has a big performance issue. If possible try to use RN image tag. Otherwise, try these solutions:.
Read more >
How Does SVG Enhance Web Performance?
Learn how to optimize your web performance and scalability with SVG vector graphics and know the difference between vector and bitmap!
Read more >
5 Gotchas You're Gonna Face Getting Inline SVG Into ...
Their 2.0 release is using an SVG icon system, and here he shares some issues he's ran into along the way, and how...
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