ArcObjects空間フィルタと属性フィルタの都市伝説


属性のみの検索でも「QueryFilterClass」でなく「SpatialFilterClass」を使うと速いと言う都市伝説を検証してみた。

5万件のランダム地点に対して、100件抜く場合は数ミリ秒程度の効果あり?

いずれにせよデータソースがDBMSの場合はどうなるか分からない
得られるマージンが少ないので素直にQueryFileter使おうかと思う。。

空間フィルタの方が無駄処理しそうなものだが、結果は?
実装的には検索条件の保持クラスと言うだけのはずだが。。

以下のコードで空間先、属性後等入れ替えて確認10件程度の場合は属性が数ミリ秒速いが
恐らく誤差レベルなので。。

文字列やインデックスついていない属性において挙動が違うのだろうか?
今ひとつ何ともいい難い結果となった。

public static void TEST(string gdbPath, string name)
{
    using (ComReleaser lifetime = new ComReleaser())
    {
        Type t = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
        IWorkspaceFactory2 wsf = (IWorkspaceFactory2)Activator.CreateInstance(t);
        lifetime.ManageLifetime(wsf);

        //string where = "OID IN (0,1,2,1000,1222,3333,4678,2524,5747,8888)";
        string where = "OID IN (1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105)";
            
        IFeatureWorkspace fw = (IFeatureWorkspace)wsf.OpenFromFile(gdbPath, 0);
        lifetime.ManageLifetime(fw);
        IFeatureClass fc = fw.OpenFeatureClass(name);
        lifetime.ManageLifetime(fc);


        ISpatialFilter spFilter = new SpatialFilterClass();
        lifetime.ManageLifetime(spFilter);
        spFilter.WhereClause = where;
        spFilter.SearchOrder = esriSearchOrder.esriSearchOrderAttribute;
        spFilter.AddField(fc.OIDFieldName);
        spFilter.AddField(fc.ShapeFieldName);


        DateTime dt = DateTime.Now;

        IFeature feature = null;
        IFeatureCursor cursor = fc.Search(spFilter, true);
        lifetime.ManageLifetime(cursor);

        while ((feature = cursor.NextFeature()) != null)
        {
            Console.WriteLine(feature.OID);
        }

        TimeSpan spTs = DateTime.Now - dt;

        dt = DateTime.Now;

        IQueryFilter qFilter = new QueryFilterClass();
        lifetime.ManageLifetime(qFilter);
        qFilter.WhereClause = where;
        qFilter.AddField(fc.OIDFieldName);
        qFilter.AddField(fc.ShapeFieldName);
        lifetime.ManageLifetime(qFilter);

            
        feature = null;
        cursor = fc.Search(qFilter, true);
        lifetime.ManageLifetime(cursor);

        while ((feature = cursor.NextFeature()) != null)
        {
            Console.WriteLine(feature.OID);
        }

        TimeSpan qTs = DateTime.Now - dt;

        string msg = string.Format("ISpatial:{0}ms\nIQuery:{1}ms", spTs.Milliseconds, qTs.Milliseconds);
        Console.WriteLine(msg);

    }//end com
}//end method
カテゴリー: 開発 タグ: パーマリンク