C++常見空間索引效率對比

第一篇博客,感謝下帶我這個門外漢入了GIS行業的導師李治江老師~


由於打算寫一個空間數據引擎,在空間索引和屬性索引方面蒐集了一些開源實現,本文用以對比C++ GIS開發中常見的空間索引實現的效率


測試環境

操作系統 Windows 7 Professional SP1
CPU Inter Core i7-3520M @ 2.9GHz
內存 8GB
系統盤硬盤 SanDisk SDSSDXP120G
數據盤硬盤 HGST HTS725050A7E630
開發環境 Visual Studio 2008 SP1

實驗對象

空間篩選的大致流程基本都是:
1. 矩形框初篩,通過待查詢矩形框與數據外包矩形相交快速判斷
2.對初篩後縮小了的數據集進行相交、包含、相切、相離等精確判斷
空間索引就是提高第一步矩形運算效率的算法
其實不管什麼實現,矩形相交的快速判斷方法是固定的,四個邊界數值的比較,除非寫彙編、寫機器碼,否則不太有提升空間。而空間索引的算法優劣,主要在於如何減少無關數據的訪問次數
空間數據至少是二維數據,常用的一維索引(如BTree/Bitmap索引等)無法滿足需求,常用的空間索引算法有BSP樹、K-D-B樹、R樹、R+樹和CELL樹(摘自百度百科,補充四叉樹)。
本文要對比的是一些常見的C++空間索引開源實現
loop 最原始的循環,每個節點都訪問
shapelib-qix shapelib提供的默認空間索引算法,基於四叉樹的實現。支持硬盤、內存兩種模式
shapelib-sbn 從gdal-1.10起添加的對ArcGIS生成的sbn格式的空間索引支持,筆者將其編譯入了最新的shapelib中。僅支持硬盤模式
geos geos提供了若干種空間索引算法,本文對其中的STRTree和QuadTree分別進行了測試。僅支持內存模式
spatialindex 提供了多種基於RTree的空間索引算法,還包括時空GIS所需要的多版本索引算法等。本文僅對二維數據索引,因此僅探討RTree。支持硬盤、內存兩種模式

對比方法

測試數據

鄭州市矢量數據
數據類型:Line
數據量:1554304條
x_min:454250.000000
x_max:479750.045600
y_min:3839499.634654
y_max:3862000.032000
空間參考:Xian_1980_3_Degree_GK_CM_114E

對比邏輯

對上述數據的打開數據、創建索引、索引查詢範圍R內數據n次、相關清理作爲一次完整流程,記錄索引創建時間、索引內存佔用情況、查詢時間、查詢到數據結果數量作爲橫向對比參考。重複如上操作t次,取平均值。
其中
R:x_min:465701.923
R:x_max:469994.306
R:y_min:3852567.173
R:y_max:3855717.229
n:100
t:5

對比結果

Method Mode Insert(ms) Memory(MB) Query(ms) QueryCount 說明
Loop-vector Memory 2801.2 77.274219 1523.8 60854 使用std::vector作爲數據的存取容器
Loop-list Memory 2856.4 106.534375 1367.2 60854
使用std::list作爲數據的存取容器
Loop Disk 0.0 0.000000 264532.0 60854
打開數據逐條IO判斷
Qix Memory 3499.8 75.525781 745.8 62240 在內存中創建qix索引查詢
Qix Disk 3730.6 0.000000 2010.2 62240 使用硬盤中的qix索引查詢
Sbn Disk 0.0 10.158594 898.2 63047 使用硬盤中的sbn索引查詢
Geos-STRTree Memory 3100.4 136.578125 2878.8 60854
在內存中創建geos::strtree索引查詢
Geos-QuadTree Memory 4194.4 302.792969 383.4 64288 在內存中創建geos::quadtree索引查詢
SpatialIndex-RTree Memory 83795.2 72.734375 3087.8 60854
在內存中創建rtree索引查詢(原始insert接口)
SpatialIndex-RTree Memory-BulkLoad 13041.0 90.471875 2874.6 60854
在內存中創建rtree索引查詢(使用bulkload提升創建速度)
SpatialIndex-RTree Disk-BulkLoad 13348.8 18.336719 4249.6 60854
使用硬盤中的rtree索引查詢(使用bulkload提升創建速度)


優缺點對比


優點 缺點
qix 1.索引速度極快
2.支持硬盤、內存兩種模式
1.僅支持shp數據(仔細研究下代碼應該也能把索引部分跟SHPHandle的耦合解開)
sbn 1.硬盤索引速度極快 1.暫無生成sbn的代碼,僅能用作只讀索引
2.僅支持shp數據
3.僅支持硬盤模式(不過速度其實已經很快了,是否內存化可能不太重要)
geos 1.內存四叉樹索引速度爲最快 1.僅支持內存模式(對數據量過大的情況應對性不好)
2.geos源碼中存在一處內存釋放未決,需要使用者對插入索引樹的內存做管理,使用較爲不便(建議修改源碼)
3.內存佔用較大
spatialindex 1.支持硬盤、內存兩種模式 1.索引生成較慢(做大數據量的實時編輯數據時可能會有效率問題)

綜上考慮,可能會在後續的索引中使用spatialindex

對比缺陷

哎,說到缺陷,還請各位看客多多留下寶貴意見

1.最最百思不得其解的是,除了四叉樹的兩個索引算法和sbn索引,其他索引居然都比內存生生循環要慢,真是打臉打的厲害啊。。。

  2014-09-10 自圓其說的一種解釋

2.對比沒有考慮不同數據特點下索引算法的優劣,如數據外包矩形均勻分佈或有明顯集中是否有影響

3.對不同算法中的可控參數尚未做縱向對比

4.未對比更大數據量的索引穩定性(之前使用過sqlite的rtree,發現超過1000萬條記錄就會導致索引建立極慢無比,且因爲sqlite的rtree實現是通過虛表+關聯外鍵方式實現,實用性較差,因此沒有放在此次對比中)


附上源碼,敬請指正:

http://pan.baidu.com/s/1kTJttrh


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章