Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance collapse with many Refresh calls and zooming out #2605

Open
pauldendulk opened this issue Apr 22, 2024 · 2 comments
Open

Performance collapse with many Refresh calls and zooming out #2605

pauldendulk opened this issue Apr 22, 2024 · 2 comments
Labels

Comments

@pauldendulk
Copy link
Member

pauldendulk commented Apr 22, 2024

Mapsui Version
Current master

Mapsui Platform
Tested on WPF where it was severe. Also on Avalonia where it was less severe but still clearly there.

Device
Windows Desktop

Describe the bug
The application becomes extremely sluggish when maximally zoomed out.

To Reproduce
When running the sample pasted below and zooming out so that only one tile is rendered performance significantly decreases. Even though less needs to be rendered (just one tile instead of thirty-two).

using Mapsui.Extensions;
using System;
using System.Threading.Tasks;
using System.Timers;
using Mapsui.Tiling;
using Mapsui.Widgets.InfoWidgets;

namespace Mapsui.Samples.Common.Maps.Geometries;

public sealed class ManyRefreshesSample : ISample, IDisposable
{
    private bool _disposed;

    public string Name => "Many Refreshes";
    public string Category => "Performance";

    private readonly Timer _timer = new(1);

    public Task<Map> CreateMapAsync()
    {
        var map = new Map();

        map.Layers.Add(OpenStreetMap.CreateTileLayer());
        map.Navigator.ZoomToBox(map.Layers[0].Extent);
        map.Widgets.Add(new MapInfoWidget(map));

        InitializeTimer(_timer, map);

        return Task.FromResult(map);
    }

    private static void InitializeTimer(Timer timer, Map map)
    {
        var random = new Random(38445);
        timer.Elapsed += (sender, args) => TimerElapsed(map);
        timer.Start();
    }

    private static void TimerElapsed(Map map)
    {
        for (var i = 0; i < 1000; i++)
            map.Refresh();
    }

    public void Dispose()
    {
        if (_disposed)
            return;

        _timer.Dispose();

        _disposed = true;
    }
}
@pauldendulk
Copy link
Member Author

Analysis

It is counter intuitive that the application gets slower when only one tile needs to be rendered. It should be faster. In fact when zooming out maximally the application hardly responds at all.

I ran all kinds of analysis tools and custom configurations. What seems to be happening is that because everything is faster there are more calls to start and stop the FetchWorkers (which rapidly conclude that there is nothing to fetch). I think the rapid creation and deletion of threads within the worker put a high load on the garbage collector and this disturbed other processes which cascaded things further.

@pauldendulk pauldendulk changed the title Performance degradation with many Refresh calls and zooming out. Performance degradation with many Refresh calls and zooming out Apr 22, 2024
@pauldendulk
Copy link
Member Author

pauldendulk commented Apr 23, 2024

I updated the sample to the most minimal things needed to reproduce the problem. The essential thing is the high number of refresh calls. They are now at 1 million per second. That is pretty extreme and you might argue that this would cause problems in any software, but the remarkable thing is that is does not cause problems at zoom level 5 to 20, but it does at level 1 when rendering takes less time.

@pauldendulk pauldendulk changed the title Performance degradation with many Refresh calls and zooming out Performance collapse with many Refresh calls and zooming out Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant