2013-02-07 72 views
1

我要尋找一個集合類用於以下情形:收集用於快速讀取C#

  • 快速收集查找,每次一個項目。
  • 集合包含大約300 K項目。
  • 收集人羣速度可能並不重要,但也非常快。
  • 沒有更新/刪除一次收集加載Ip2Location類型的項目將被填充到收藏

則需要使用/插入:

對收集
public class Ip2Location 
{ 
    public long IpFrom {get; set;} 
    public long IpTo {get; set;} 
    public string Country {get; set;} 
} 

IpFrom  IpTo  Country 
16909056 16909311 AU 
16909312 16941055 US 

項目查找通過完成一個指定的IP,像這樣:

IpFrom < currentIp < IpTo 

任何想法,包括參考鏈接,將非常感激!

比較:HashSet, SortedSet

有沒有更好的集合類?

參考: http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx

更新:使用Array.BinarySearch

問題:在下面的鏈接比較表

var index = Array.BinarySearch(ipCountries, new IpCountry { IpFrom = 16909056}, new Ip2LocationComparer()); 

它工作在排小數字,沒有按在300k項目中工作(例如,索引是 - (totalrow + 1))。搜索項目被加載到300 K項目集合中。

 public class Ip2LocationComparer: IComparer<IpCountry> 
     { 
      public int Compare(IpCountry x, IpCountry y) 
      { 
       if (x != null && y != null) 
        return (x.IpFrom <= y.IpFrom && y.IpFrom <= x.IpTo)? 0 : -1; 

       return -1; 

      } 
     } 

更新2

我把它改成下面

public class Ip2LocationComparer: IComparer<IpCountry> 
      { 
       public int Compare(IpCountry x, IpCountry y) 
       { 
     if (x != null && y != null) 

      { 
       if (x.IpFrom > y.IpFrom) 
        return 1; 

       if (x.IpFrom < y.IpFrom) 
        return -1; 

       if (x.IpFrom == y.IpFrom) 
       { 
        if (y.IpFrom > x.IpTo) 
         return 1; 

        if (y.IpFrom < x.IpTo) 
         return -1; 

       } 

      } 

      return 0; 
} 

但是從二分查找該指數的回報仍然是nagtive,這是匹配的項目和後續項目之間的權利。例如如果我的搜索IpFrom是3,索引是在2和4之間。爲什麼它不返回2?我還沒有測試IpTo場景。

任何想法,將不勝感激!

+0

您的搜索方法不起作用,因爲您的比較器已損壞。如果x在「之前」y,則需要返回-1;如果x和y相同,則返回0;如果y在x之後,則返回1。在你的情況下,你幾乎可以肯定希望實現是'x.IpFrom.CompareTo(y.IpFrom),如果結果爲零,也返回'IpTo'比較(也是一個空檢查)。這會給你第一個範圍內的項目。然後繼續下去,直到你點擊一個項目,其中'to'範圍在當前項目之前,然後完成。 – Servy

+0

感謝您的評論。我發佈了更新2.請看看,任何想法將非常appreicated! – Pingpong

+0

你的比較器現在工作正常。你可以用更少的代碼來完成,但是你所擁有的沒有任何問題。 BinarySearch被設計爲返回一個負值;只需查看MSDN上的方法和示例的文檔即可查看它的正確用法。 – Servy

回答

4

您可以將其存儲在數組中。

如果您在填充後對數組進行排序,那麼BinarySearch將是查找currentIp落在哪裏的非常快速的方式。

+0

謝謝!那麼HashSet和SortedSet呢?你的意思是由IpFrom排序?因爲IpFrom是唯一的。 – Pingpong

+0

不,你想要一個數組和二進制搜索你正在做的事情。哈希集合或排序列表必須查找,即使您可以遍歷它們,它們也不會像二進制搜索那樣具有性能。 –

+0

@Pingpong按照IpFrom排序的普通數組可以在IpFrom上進行二分搜索 –

0

數據結構明智,你可以嘗試一個字典或排序列表,雖然有300000項,你可能會遇到問題。不過,我很好奇聽到結果。使用BinarySearch的普通數組也可能不是一個錯誤的選項。

您也可以考慮利用機器上的所有核心進行快速查找。您可以在大多數分析器上使用.AsParallel() extension method,這些分析器將準備查詢多個內核的集合。