Skip to content
Permalink
Browse files
Add a small cache for geometries built from WKT strings
This can be very expensive, so by caching them we can save a lot of
time

A quick benchtest using a delimited text layer with WKT strings
for geometries:

Before: average redraw time: 3338 ms
After: average redraw time: 670 ms

(Of course, this benefit assumes that all the layer's geometries
can fit in the cache. But even when the cache is exhausted there's
no noticable drop in performance)
  • Loading branch information
nyalldawson committed Nov 15, 2021
1 parent e0447a1 commit 87452aa88eef77f811e5f104795384f564e8e99e
Showing with 14 additions and 6 deletions.
  1. +14 −6 src/core/geometry/qgsgeometry.cpp
@@ -18,6 +18,7 @@ email : morb at ozemail dot com dot au
#include <cstdio>
#include <cmath>
#include <nlohmann/json.hpp>
#include <QCache>

#include "qgis.h"
#include "qgsgeometry.h"
@@ -53,6 +54,7 @@ email : morb at ozemail dot com dot au
#include "qgslinestring.h"
#include "qgscircle.h"
#include "qgscurve.h"
#include "qgsreadwritelocker.h"

struct QgsGeometryPrivate
{
@@ -159,12 +161,18 @@ bool QgsGeometry::isNull() const

QgsGeometry QgsGeometry::fromWkt( const QString &wkt )
{
std::unique_ptr< QgsAbstractGeometry > geom = QgsGeometryFactory::geomFromWkt( wkt );
if ( !geom )
{
return QgsGeometry();
}
return QgsGeometry( std::move( geom ) );
static QCache< QString, QgsGeometry > sWktCache( 2000 ); // store up to 2000 geometries
static QReadWriteLock sCacheLock;

QgsReadWriteLocker lock( sCacheLock, QgsReadWriteLocker::Read );
if ( const QgsGeometry *cached = sWktCache.object( wkt ) )
return *cached;
lock.unlock();

const QgsGeometry result( QgsGeometryFactory::geomFromWkt( wkt ) );
lock.changeMode( QgsReadWriteLocker::Write );
sWktCache.insert( wkt, new QgsGeometry( result ), 1 );
return result;
}

QgsGeometry QgsGeometry::fromPointXY( const QgsPointXY &point )

0 comments on commit 87452aa

Please sign in to comment.