[英].net collection for fast filtering (sorted collection)
在分析一個非常慢的方法時,我發現滯后是搜索和過濾集合。
該方法執行以下操作(按順序)。 根據剖析器,80%的時間花在步驟1-3上。
.RangeFromTo()
) Right()
) .RangeFromTo()
過濾給定范圍,例如:
[3,7,9,12].RangeFromTo(2,9) -> [3,7,9]
[3,7,9,12].RangeFromTo(2,8) -> [3,7]
[3,7,9,12].RangeFromTo(7,13) -> [7,9,12]
[3,7,9,12].RangeFromTo(13,14) -> [ ]
.Right()
在集合中找到一個元素,並在列表中為您提供下一個元素。 如果元素不存在,它會為您提供最接近右邊的元素。 例如:
[3,7,9,12].Right(0) -> 3
[3,7,9,12].Right(3) -> 7
[3,7,9,12].Right(4) -> 7
[3,7,9,12].Right(12) -> null
目前該集合使用C5的SortedArray
( https://github.com/sestoft/C5/ )。 我可以使用更合適的系列嗎?
注意:步驟1.大約占總時間的30%。 如果我改用List,那么protobuf實際上減少了40%的反序列化時間! 我想當插入到SortedArray時,集合不知道數據已經排序並且正在進行大量的工作。 理想的集合(如果存在)也應該能夠繞過它。
編輯:澄清一下,列表大約1000-5000,有90k個不同的集合! 有問題的方法需要在內存中加載所有集合以執行某些業務任務。
編輯2:我在這里添加了一些示例基准:
https://github.com/cchanpromys/so_19188345
它將C5的SortedArray
與.Net的SortedSet
進行比較。 到目前為止,結果如下:
C5 sorted array deserialize took 904
Sorted set deserialize took 1040
C5 sorted array .Right() took 5
Sorted set .Right() took 798 <--- Not sure what happened here...
C5 sorted array .RangeFromTo() took 217
Sorted set .RangeFromTo() took 140
編輯3這超出了我的預期,但我最終得到了一個列表的自定義實現。
我遇到的問題是SortedArray的Find操作(通常)需要O(Log(N)),而我希望它是O(1)操作。
此外,列表按性質排序,您永遠不會添加到列表的中間。
所以我最終實現了一個具有內部索引器數組的列表,例如:
例如:
indexer: [0,0,0,0,1,1,1,1,2,2]
list: [3,7,9]
所以.Right(3)
將是list[indexer[3]++]
。
代碼可以在這里找到。
很難相信這種類型的列表還沒有在互聯網上的某個地方實現。 如果可能的話,我想使用一個庫,所以我不必管理我自己的列表。
互聯網上是否存在此類實施?
如果您的陣列足夠小(可能低於10-20個元素),那么簡單的線性搜索很有可能足夠好(在某些情況下, List
會在測量中更快地顯示)並且您可以使用Where
/ TakeWhile
縮小范圍:
(new[]{3,7,9,12}).Where(i => i>= 2).TakeWhile(i => i <= 9)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.