Skip to content

Improve performance of CRS zoom & scale methods #2183

Description

@monsieurtanuki

What do you want implemented?

Not sure how much performance improvements we can get from this.

We have a couple of methods for projecting LatLng.

  (double, double) latLngToXY(LatLng latlng, double scale);

  /// Similar to [latLngToXY] but converts the XY coordinates to an [Offset].
  Offset latLngToOffset(LatLng latlng, double zoom) {
    final (x, y) = latLngToXY(checkLatLng(latlng), scale(zoom));
    return Offset(x, y);
  }

The most used method is latLngToOffset, that computes a scale.

  /// Zoom to Scale function.
  double scale(double zoom) => 256.0 * math.pow(2, zoom);

The thing is that we constantly compute math.pow(2, zoom).
Given that most of the time (always?) we work on a single zoom level for all points, we could cache the latest zoom/scale values.
Something like that:

  double _latestZoom = -1;
  double _latestScale = -1;

  double scale(double zoom) {
    if ((_latestZoom == -1 && _latestScale == -1) || _latestZoom != zoom) {
      _latestZoom = zoom;
      return _latestScale = 256.0 * math.pow(2, zoom);
    }
    return _latestScale;
  }

What other alternatives are available?

No response

Can you provide any other information?

No response

Activity

  1. monsieurtanuki commented on Jan 25, 2026

    @monsieurtanuki
    ContributorAuthor

    And of course, the zoom method could be improved similarly:

    double zoom(double scale) => math.log(scale / 256) / math.ln2;
  2. monsieurtanuki commented on Jan 25, 2026

    @monsieurtanuki
    ContributorAuthor

    Looks like it would mean making Crs not const anymore. Which is problematic as we have default Crs constructor parameters: we need the default Crs value to be const.
    Or... we create not const classes on top, that just override methods scale and zoom. As "optimized" versions.

  3. JaffaKetchup commented on Mar 1, 2026

    @JaffaKetchup
    Member

    This could be interesting to look into. I think we would need to retain const Crs classes, and layer the performance improvements on top as you said. But we would need to run a benchmark.

  4. Brijesh-gangwar commented on Mar 17, 2026

    @Brijesh-gangwar

    Hi @JaffaKetchup and @monsieurtanuki is anyone already working on this? I'd love to take it up if it's still open. Thanks!

    I ran a quick benchmark (median ns/op, 9 rounds):

    Operation Base Static cache Layered cache
    scale same-zoom 32.9 10.3 7.2
    zoom same-scale 26.9 18.1 15.3
    latLngToXY same-zoom 111.3 73.7 71.3
    alternating zoom (worst-case) 30.1 76.1 61.3

    Summary of findings:

    • Layered cached CRSs (opt-in) keep const defaults intact and match the "layer on top" idea discussed above.
    • Benchmarks show clear wins in hot paths when zoom is stable (common during rendering)

    Happy to work on this issue with cached CRS subclasses + benchmark if this is still open!

  5. monsieurtanuki commented on Mar 17, 2026

    @monsieurtanuki
    ContributorAuthor

    Hi @Brijesh-gangwar! I haven't started anything, so feel free to benchmark!

  6. JaffaKetchup commented on Mar 17, 2026

    @JaffaKetchup
    Member

    Thanks for looking into this @Brijesh-gangwar !

    We'd be more than happy to accept a PR. To make your benchmark reproducible for everyone else, it might be easiest to add to benchmark/crs.dart if needed (or it might actually have everything already needed) - we can compare between commits to see performance changes.

  7. Brijesh-gangwar commented on Mar 17, 2026

    @Brijesh-gangwar

    Hi @monsieurtanuki @JaffaKetchup
    Ok
    I will raise pr soon

  8. added
    P: 3 (low)(Default priority for feature requests)
    and removed
    P: 3 (low)(Default priority for feature requests)
    on Apr 13, 2026
  9. updated Priority Low and Effort Medium on Sep 3, 2026
  10. changed the title [-]Performance improvement with zoom/scale[/-] [+]Improve performance of CRS `zoom` & `scale` methods[/+] on Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    Priority

    Low

    Effort

    Medium

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions