簡體   English   中英

用於快速過濾的.net集合(已排序集合)

[英].net collection for fast filtering (sorted collection)

在分析一個非常慢的方法時,我發現滯后是搜索和過濾集合。

該方法執行以下操作(按順序)。 根據剖析器,80%的時間花在步驟1-3上。

  1. 從文件中讀取已排序的集合並使用Protobuf-net(v2)進行反序列化
  2. 從排序的集合中,基於開始和結束整數進行過濾(名稱.RangeFromTo()
  3. 從相同的排序集合中,獲取集合的下一個元素(名稱。 Right()
  4. 執行一些任務......

.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的SortedArrayhttps://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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM