Opened 49 minutes ago
Last modified 49 minutes ago
#37498 assigned Cleanup/optimization
Improve GEOSGeometry.tuple performance
| Reported by: | David Smith | Owned by: | David Smith |
|---|---|---|---|
| Component: | GIS | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
In PR, David has a proof of concept for improving the performance of the GEOSGeometry.tuple property for geometries with many coordinates, from 1.4x - 46x faster depending on the number of coordinates.
Addressing this will make it more practical to use this property when rearchitecting some other geometry construction paths in GeoDjango.
Using one of the fixtures (a Polygon, with 799 coords in one coordinate sequence) from the test suite.
Set up
In [1]: from django.contrib.gis.gdal import DataSource ...: from django.contrib.gis.geos import GEOSGeometry ...: ...: source = DataSource("tests/gis_tests/data/counties/counties.shp") ...: geometry = GEOSGeometry(memoryview(source[0][1].geom.wkb))
Current
In [3]: %timeit geometry.tuple 3.4 ms ± 35.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Proposed
In [3]: %timeit geometry.tuple 73.2 μs ± 406 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
A ~46x speedup.
This is a favourable example as it is a single 'large' geometry. The impact will vary depending upon the geometry. A collection of many geometries with each with a small number of coordinates, would perform differently. For example this item from the test suite has 9 sub-geometries with 21 points.
In [1]: import json ...: from pathlib import Path ...: from django.contrib.gis.geos import GEOSGeometry ...: ...: data = json.loads( ...: Path("tests/gis_tests/data/geometries.json").read_text() ...: ) ...: geometry = GEOSGeometry(data["multilinestrings"][1]["wkt"])
Current
In [3]: %timeit geometry.tuple 306 μs ± 3.56 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Proposed
In [2]: %timeit geometry.tuple 212 μs ± 3.05 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
A 1.4x improvement.