1

以下のシナリオのコレクション クラスを探しています。

  • 一度に 1 アイテムずつ、コレクションをすばやく検索します。
  • コレクションには約 30 万点のアイテムが含まれています。
  • コレクションの作成速度は重要ではないかもしれませんが、理想的には高速でもあります。
  • コレクションがロードされると、更新/削除/挿入は必要ありません

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;
}

しかし、BinarySearch からのインデックスの戻り値はまだネガティブで、一致するアイテムとフォローするアイテムのちょうど中間にあります。たとえば、検索 IpFrom が 3 の場合、インデックスは 2 から 4 の間です。なぜ 2 が返されないのですか? IpTo シナリオはまだテストしていません。

どんなアイデアでも大歓迎です!

4

2 に答える 2

4

これを配列に格納できます。

入力後に配列をソートした場合、BinarySearchcurrentIpは、該当する場所を検索するための非常に高速な方法になります。

于 2013-02-07T23:17:46.390 に答える
0

データ構造に関しては、辞書またはソートされたリストを試すことができますが、300000アイテムでは、問題が発生する可能性があります。でも、その結果を聞いてみたいと思います。BinarySearchを使用した単純な配列も、悪いオプションではない可能性があります。

すばやく検索するために、マシン上のすべてのコアを利用することも検討してください。ほとんどのコレクションで.AsParallel()拡張メソッドを使用できます。これにより、複数のコアでクエリを実行するためのコレクションが準備されます。

于 2013-02-07T23:20:51.297 に答える