第一篇部落格,感謝下帶我這個門外漢入了gis行業的導師李治江老師~
由於打算寫乙個空間資料引擎,在空間索引和屬性索引方面蒐集了一些開源實現,本文用以對比c++ gis開發中常見的空間索引實現的效率
作業系統
windows 7 professional sp1
cpuinter core i7-3520m @ 2.9ghz
記憶體8gb
系統盤硬碟
sandisk sdssdxp120g
資料盤硬碟
hgst hts725050a7e630
開發環境
visual studio 2008 sp1
空間篩選的大致流程基本都是:
1. 矩形框初篩,通過待查詢矩形框與資料外包矩形相交快速判斷
2.對初篩後縮小了的資料集進行相交、包含、相切、相離等精確判斷
空間索引就是提高第一步矩形運算效率的演算法
其實不管什麼實現,矩形相交的快速判斷方法是固定的,四個邊界數值的比較,除非寫彙編、寫機器碼,否則不太有提公升空間。而空間索引的演算法優劣,主要在於如何減少無關資料的訪問次數
本文要對比的是一些常見的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.00.000000
264532.0
60854
開啟資料逐條io判斷
qixmemory
3499.8
75.525781
745.8
62240
在記憶體中建立qix索引查詢
qixdisk
3730.6
0.000000
2010.2
62240
使用硬碟中的qix索引查詢
sbndisk
0.010.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的耦合解開)
sbn1.硬碟索引速度極快
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實現是通過虛表+關聯外來鍵方式實現,實用性較差,因此沒有放在此次對比中)
附上原始碼,敬請指正:
c 反射用法及效率對比
反射例項化類 通過反射例項化物件,要比直接 new 要慢 50 倍左右 assembly.createinstance 要比 activator.createinstance 慢,主要的效能損耗在 assembly.gettype 反射呼叫類的方法 class program static void...
mysql下普通索引和唯一索引的效率對比
1 普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 wherecolumn 或排序條件 orderbycolumn 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...
C協程實現的效率對比
前段時間實現的c協程依賴棧傳遞引數,在開啟優化時會導致錯誤,於是實現了乙個ucontext的版本,但ucontext的切換效率太差了,在我的機器上執行4000w次切換需要11秒左右,這達不到我的要求,所以重新設計了實現,使得在開啟優化時也能得到正確的結果.並且效率也令人滿意,4000w次切換僅需要7...