C 常見空間索引效率對比

2021-06-25 13:15:34 字數 3600 閱讀 9663

第一篇部落格,感謝下帶我這個門外漢入了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...