Skip to content

Commit c6565ef

Browse files
committedJan 2, 2020
[processing] Ensure faster predicates are always tested first before slower predicates
Because we may be able to bypass the slower checks if the faster ones pass first
1 parent 16c83e0 commit c6565ef

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed
 

‎src/analysis/processing/qgsalgorithmjoinbylocation.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ QVariantMap QgsJoinByLocationAlgorithm::processAlgorithm( const QVariantMap &par
133133
const QStringList joinedFieldNames = parameterAsFields( parameters, QStringLiteral( "JOIN_FIELDS" ), context );
134134

135135
mPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
136+
sortPredicates( mPredicates );
136137

137138
QString prefix = parameterAsString( parameters, QStringLiteral( "PREFIX" ), context );
138139

@@ -303,6 +304,32 @@ bool QgsJoinByLocationAlgorithm::featureFilter( const QgsFeature &feature, QgsGe
303304
return ok;
304305
}
305306

307+
void QgsJoinByLocationAlgorithm::sortPredicates( QList<int> &predicates )
308+
{
309+
// Sort predicate list so that faster predicates are earlier in the list
310+
// Some predicates in GEOS do not have prepared geometry implementations, and are slow to calculate. So if users
311+
// are testing multiple predicates, make sure the optimised ones are always tested first just in case we can shortcut
312+
// these slower ones
313+
314+
std::sort( predicates.begin(), predicates.end(), []( int a, int b ) -> bool
315+
{
316+
// return true if predicate a is faster than b
317+
318+
if ( a == 0 ) // intersects is fastest
319+
return true;
320+
else if ( b == 0 )
321+
return false;
322+
323+
else if ( a == 5 ) // contains is fast for polygons
324+
return true;
325+
else if ( b == 5 )
326+
return false;
327+
328+
// that's it, the rest don't have optimised prepared methods (as of GEOS 3.8)
329+
return a < b;
330+
} );
331+
}
332+
306333
bool QgsJoinByLocationAlgorithm::processFeatures( QgsFeature &joinFeature, QgsProcessingFeedback *feedback )
307334
{
308335
if ( !joinFeature.hasGeometry() )

‎src/analysis/processing/qgsalgorithmjoinbylocation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class QgsJoinByLocationAlgorithm : public QgsProcessingAlgorithm
6767
std::unique_ptr< QgsFeatureSink > mUnjoinedFeatures;
6868
JoinMethod mJoinMethod = OneToMany;
6969
QList<int> mPredicates;
70+
71+
static void sortPredicates( QList<int > &predicates );
7072
};
7173

7274
///@endcond PRIVATE

0 commit comments

Comments
 (0)
Please sign in to comment.