SVG Pins: performance issues
See original GitHub issueI 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):
-
For svg pins, the svg data is stored as a string (
Pin.Svg). InPin.CreateFeaturethis is then converted (copied) into a byte array viaEncoding.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? -
IIUC the
BitmapRegistryclass 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 (sincePin.CreateFeaturealwas seems to callBitmapRegistry.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:
- Created 3 years ago
- Comments:50 (50 by maintainers)

Top Related StackOverflow Question
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
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
This can be closed. Most of the performance issues described above were basically fixed for me with #1192.