Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
nyalldawson committed Jan 2, 2020
1 parent 16c83e0 commit c6565ef
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/analysis/processing/qgsalgorithmjoinbylocation.cpp
Expand Up @@ -133,6 +133,7 @@ QVariantMap QgsJoinByLocationAlgorithm::processAlgorithm( const QVariantMap &par
const QStringList joinedFieldNames = parameterAsFields( parameters, QStringLiteral( "JOIN_FIELDS" ), context );

mPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
sortPredicates( mPredicates );

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

Expand Down Expand Up @@ -303,6 +304,32 @@ bool QgsJoinByLocationAlgorithm::featureFilter( const QgsFeature &feature, QgsGe
return ok;
}

void QgsJoinByLocationAlgorithm::sortPredicates( QList<int> &predicates )
{
// Sort predicate list so that faster predicates are earlier in the list
// Some predicates in GEOS do not have prepared geometry implementations, and are slow to calculate. So if users
// are testing multiple predicates, make sure the optimised ones are always tested first just in case we can shortcut
// these slower ones

std::sort( predicates.begin(), predicates.end(), []( int a, int b ) -> bool
{
// return true if predicate a is faster than b

if ( a == 0 ) // intersects is fastest
return true;
else if ( b == 0 )
return false;

else if ( a == 5 ) // contains is fast for polygons
return true;
else if ( b == 5 )
return false;

// that's it, the rest don't have optimised prepared methods (as of GEOS 3.8)
return a < b;
} );
}

bool QgsJoinByLocationAlgorithm::processFeatures( QgsFeature &joinFeature, QgsProcessingFeedback *feedback )
{
if ( !joinFeature.hasGeometry() )
Expand Down
2 changes: 2 additions & 0 deletions src/analysis/processing/qgsalgorithmjoinbylocation.h
Expand Up @@ -67,6 +67,8 @@ class QgsJoinByLocationAlgorithm : public QgsProcessingAlgorithm
std::unique_ptr< QgsFeatureSink > mUnjoinedFeatures;
JoinMethod mJoinMethod = OneToMany;
QList<int> mPredicates;

static void sortPredicates( QList<int > &predicates );
};

///@endcond PRIVATE
Expand Down

0 comments on commit c6565ef

Please sign in to comment.