twhiteaker

Choice of esriSpatialRelEnum can slow IFeatureCursor NextFeature performance

Discussion created by twhiteaker on Sep 13, 2011
Latest reply on Nov 7, 2011 by twhiteaker
Environment: Programming add-ins for ArcGIS 10.0.

Has anyone noticed performance differences when looping through features returned from a search, depending on which esriSpatialRelEnum you used?  esriSpatialRelIntersects seems to be much faster than esriSpatialRelContains.  Note that the search itself is fast, but what is slow is looping through features in the cursor returned from the search.  I didn't think esriSpatialRelEnum had anything to do with IFeatureCursor.NextFeature.

Am I doing something wrong with my setup of the spatial filter?  Is there a workaround?

To test, create an add-in with a button and attach this code to it.  Then add a polygon layer to ArcMap.  I used the example Globe data on my computer at C:\Program Files (x86)\ArcGIS\Desktop10.0\ArcGlobeData\continent.shp. Click the button and see how long it takes.

The code uses ESRI.ArcGIS.ADF, ESRI.ArcGIS.Carto, and ESRI.ArcGIS.Geodatabase.


// Get a polygon layer, the first layer in the map
IFeatureLayer layer = ArcMap.Document.FocusMap.Layer[0] as IFeatureLayer;
IFeatureClass featureClass = layer.FeatureClass;
// Use an ObjectID from your feature class to get a feature
IFeature feature = featureClass.GetFeature(1);

// Create a filter using geometry from the feature
ISpatialFilter filter = new SpatialFilterClass();
filter.Geometry = feature.ShapeCopy;
// esriSpatialRelIntersects is fast. esriSpatialRelContains is slow.
filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

using (ComReleaser comReleaser = new ComReleaser())
{
    IFeatureCursor cursor = featureClass.Search(filter, true);
    comReleaser.ManageLifetime(cursor);

    // Time the loop
    int counter = 0;
    DateTime d = DateTime.Now;
    while ((feature = cursor.NextFeature()) != null) // The slow part
    {
        counter++;
    }

    // Report the result
    string time = DateTime.Now.Subtract(d).TotalMilliseconds.ToString();
    string msg = counter.ToString() + " feature(s) found in " + time + " ms";
    MessageBox.Show(msg);
}

Outcomes