HashSetとリストのパフォーマンス


406

総称HashSet<T>クラスの検索パフォーマンスが総称クラスの検索パフォーマンスよりも高いことは明らかですList<T>。ハッシュベースのキーをList<T>クラスの線形アプローチと比較するだけです。

ただし、ハッシュキーの計算自体にいくつかのCPUサイクルがかかる場合があるため、少量のアイテムの場合、線形検索はの実際の代替となりHashSet<T>ます。

私の質問:損益分岐はどこですか?

シナリオを簡略化するために(そして公平を期すために)、List<T>クラスが要素のEquals()メソッドを使用してアイテムを識別すると仮定しましょう。


7
ルックアップ時間を最小限にしたい場合は、配列とソートされた配列も検討してください。この質問に適切に回答するには、ベンチマークが必要ですが、Tについて詳しく説明する必要があります。また、HashSetのパフォーマンスは、T.GetHashCode()の実行時間によって影響を受ける可能性があります。
Eldritch Conundrum 2012

回答:


819

多くの人が、スピードが実際に問題にHashSet<T>なるサイズになったら、それは常に勝つList<T>と言いますが、それはあなたが何をしているのかに依存します。

たとえばList<T>、平均して5つのアイテムしか含まないがあるとします。多数のサイクルにわたって、1つのアイテムが各サイクルで追加または削除される場合は、を使用した方がよい場合がありますList<T>

私は自分のマシンでこれをテストしました。まあ、を活用するには、非常に小さくなければなりませんList<T>。短い文字列のリストの場合、サイズ20以降のオブジェクトの場合、サイズ5以降は利点がなくなりました。

1 item LIST strs time: 617ms
1 item HASHSET strs time: 1332ms

2 item LIST strs time: 781ms
2 item HASHSET strs time: 1354ms

3 item LIST strs time: 950ms
3 item HASHSET strs time: 1405ms

4 item LIST strs time: 1126ms
4 item HASHSET strs time: 1441ms

5 item LIST strs time: 1370ms
5 item HASHSET strs time: 1452ms

6 item LIST strs time: 1481ms
6 item HASHSET strs time: 1418ms

7 item LIST strs time: 1581ms
7 item HASHSET strs time: 1464ms

8 item LIST strs time: 1726ms
8 item HASHSET strs time: 1398ms

9 item LIST strs time: 1901ms
9 item HASHSET strs time: 1433ms

1 item LIST objs time: 614ms
1 item HASHSET objs time: 1993ms

4 item LIST objs time: 837ms
4 item HASHSET objs time: 1914ms

7 item LIST objs time: 1070ms
7 item HASHSET objs time: 1900ms

10 item LIST objs time: 1267ms
10 item HASHSET objs time: 1904ms

13 item LIST objs time: 1494ms
13 item HASHSET objs time: 1893ms

16 item LIST objs time: 1695ms
16 item HASHSET objs time: 1879ms

19 item LIST objs time: 1902ms
19 item HASHSET objs time: 1950ms

22 item LIST objs time: 2136ms
22 item HASHSET objs time: 1893ms

25 item LIST objs time: 2357ms
25 item HASHSET objs time: 1826ms

28 item LIST objs time: 2555ms
28 item HASHSET objs time: 1865ms

31 item LIST objs time: 2755ms
31 item HASHSET objs time: 1963ms

34 item LIST objs time: 3025ms
34 item HASHSET objs time: 1874ms

37 item LIST objs time: 3195ms
37 item HASHSET objs time: 1958ms

40 item LIST objs time: 3401ms
40 item HASHSET objs time: 1855ms

43 item LIST objs time: 3618ms
43 item HASHSET objs time: 1869ms

46 item LIST objs time: 3883ms
46 item HASHSET objs time: 2046ms

49 item LIST objs time: 4218ms
49 item HASHSET objs time: 1873ms

これがグラフとして表示されたデータです:

ここに画像の説明を入力してください

コードは次のとおりです。

static void Main(string[] args)
{
    int times = 10000000;


    for (int listSize = 1; listSize < 10; listSize++)
    {
        List<string> list = new List<string>();
        HashSet<string> hashset = new HashSet<string>();

        for (int i = 0; i < listSize; i++)
        {
            list.Add("string" + i.ToString());
            hashset.Add("string" + i.ToString());
        }

        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            list.Remove("string0");
            list.Add("string0");
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item LIST strs time: " + timer.ElapsedMilliseconds.ToString() + "ms");


        timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            hashset.Remove("string0");
            hashset.Add("string0");
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item HASHSET strs time: " + timer.ElapsedMilliseconds.ToString() + "ms");
        Console.WriteLine();
    }


    for (int listSize = 1; listSize < 50; listSize+=3)
    {
        List<object> list = new List<object>();
        HashSet<object> hashset = new HashSet<object>();

        for (int i = 0; i < listSize; i++)
        {
            list.Add(new object());
            hashset.Add(new object());
        }

        object objToAddRem = list[0];

        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            list.Remove(objToAddRem);
            list.Add(objToAddRem);
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item LIST objs time: " + timer.ElapsedMilliseconds.ToString() + "ms");



        timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < times; i++)
        {
            hashset.Remove(objToAddRem);
            hashset.Add(objToAddRem);
        }
        timer.Stop();
        Console.WriteLine(listSize.ToString() + " item HASHSET objs time: " + timer.ElapsedMilliseconds.ToString() + "ms");
        Console.WriteLine();
    }

    Console.ReadLine();
}

8
どうもありがとうございます!これは素晴らしい説明List<T>です。ゲームエンジンよりも高速に追加および削除できるものを探していました。通常、大量のオブジェクトがあるため、この種のコレクションは完璧です。
redcodefinal

17
.NETフレームワークには実際にコレクションがあり、そこに含まれる項目の数に応じてリストとHastableの実装を切り替えます:HybridDictionary
MgSam 2013年

8
MSは非一般的なバージョンしか入手できないため、その考えを放棄したようです。
MgSam 2013年

47
この答えがいっぱいであるように、リストとハッシュセットの検索パフォーマンスに関する元の質問には答えられません。挿入と削除の速度をテストしているため、検索よりもかなり時間がかかり、パフォーマンス特性が異なります。.Containsを使用してもう一度お試しください。グラフが大幅に変化します。
ロバートマッキー

5
@hypehuman CPUはシステムメモリ内のデータを直接処理することはできませんが、メモリからキャッシュにデータをプルして処理します。移動するメモリの要求と実際に到着するメモリの間にかなりの遅延があるため、CPUは、一度に移動する連続したメモリのより大きなチャンクを要求することがよくあります。この背後にある考え方は、次の命令が必要とするメモリは、おそらく前の命令が使用するメモリに非常に近いため、すでにキャッシュにあることが多いということです。データがメモリ全体に分散している場合、幸運になる可能性が低くなります。
ロイT.

70

あなたはこれを間違って見ています。はい、リストの線形検索は、少数のアイテムのHashSetよりも優れています。ただし、パフォーマンスの違いは、通常、それほど小さいコレクションでは問題になりません。これは一般に、気にする必要のある大規模なコレクションであり、Big-Oの観点から考えるとここにあります。ただし、HashSetパフォーマンスの実際のボトルネックを測定した場合は、ハイブリッドリスト/ハッシュセットの作成を試みることができますが、SOについては質問せずに、多くの経験的パフォーマンステストを実施することで実現できます。


5
あなたが心配しなければならない大規模なコレクション。私たちはその質問をwhen small collection becomes large enough to worry about HashSet vs List?数十、数万、数十億の要素で再定義できますか?
om-nom-nom 2012年

8
いいえ、数百要素を超えるとパフォーマンスにかなりの違いが見られます。重要なのは、HashSetが得意とするアクセスのタイプを実行している場合(たとえば、セットの要素Xである場合)は常にH​​ashSetを使用することです。コレクションが小さすぎてリストが高速である場合、これらのルックアップは非常にまれです。実際にはアプリケーションのボトルネックです。それが1であると測定できる場合は、問題なく最適化を試みることができますが、それ以外の場合は時間を浪費しています。
Eloff、2012年

15
ループで何度もヒットされる小さなコレクションがある場合はどうなりますか?それは珍しいシナリオではありません。
dan-gph 2014年

3
@ om-nom-nom-ポイントはどこにあるかは問題ではないということです。なぜなら、「パフォーマンスが心配な場合は、を使用してくださいHashSet<T>List<T>高速である可能性がある少数のケースでは、違いはわずかです。 」
Scott Smith

66

動作が異なるパフォーマンスの 2つの構造を比較しても、本質的には意味がありません。意図を伝える構造を使用します。List<T>重複がなく、反復順序がそれをに匹敵するようにすることは重要ではないとあなたが言ったとしてもHashSet<T>、それを使用するのは依然として悪い選択ですList<T>フォールトトレラント性が比較的低いため、これこと。

とは言っても、パフォーマンスの他の側面いくつか見ていきます。

+------------+--------+-------------+-----------+----------+----------+-----------+
| Collection | Random | Containment | Insertion | Addition |  Removal | Memory    |
|            | access |             |           |          |          |           |
+------------+--------+-------------+-----------+----------+----------+-----------+
| List<T>    | O(1)   | O(n)        | O(n)      | O(1)*    | O(n)     | Lesser    |
| HashSet<T> | O(n)   | O(1)        | n/a       | O(1)     | O(1)     | Greater** |
+------------+--------+-------------+-----------+----------+----------+-----------+
  • どちらの場合も加算はO(1)ですが、ハッシュコードを格納する前に事前計算するコストがかかるため、HashSetでは比較的遅くなります。

  • HashSetの優れたスケーラビリティには、メモリコストがあります。すべてのエントリは、ハッシュコードとともに新しいオブジェクトとして保存されます。この記事はあなたにアイデアを与えるかもしれません。


11
私の質問(6年前)は理論上のパフォーマンスについてではありませんでした。
マイケル・ダマトフ2014年

1
HashSetはElementAt()によるランダムアクセスを許可しますが、それはO(n)時間になると思います。また、おそらく、各コレクションが重複を許可するかどうかをテーブルに入れることができます(例:リストは許可しますが、ハッシュセットは許可しません)。
Dan W

1
表の@DanWは、動作特性ではなく純粋にパフォーマンスを比較しています。ElementAtのヒントをありがとう。
nawfal

1
ElementAtはLINQの拡張機能です。自分で追加した別のメソッドでは、実行できないことや最適化することができません。ElementAtを考慮しなくても、他のすべてのメソッドがこれらのクラスに明示的に存在するため、テーブルの方が意味があると思います。
Dinerdo

1
このテーブルのおかげで、私のユースケースでは、ターゲットを有効化/無効化するたびに、値を設定されたコレクションに追加および削除する必要があり、これが正しい選択(HashSet)に役立ちました。
Casey Hofland

50

HashSet <>とList <>のどちらを使用するかは、コレクションへのアクセス方法によって決まります。アイテムの順序を保証する必要がある場合は、リストを使用してください。そうでない場合は、HashSetを使用してください。マイクロソフトにハッシュアルゴリズムとオブジェクトの実装について心配させてください。

HashSetはコレクションを列挙せずにアイテムにアクセスします(O(1)またはその近くの複雑さ)。リストは順序を保証するため、HashSetとは異なり、一部のアイテムは列挙する必要があります(O(n)の複雑度)。


リストは、インデックスによって特定の要素のオフセットを計算する可能性があります(すべての要素が同じタイプであり、同じメモリサイズを占める可能性があるため)。そのため、リストはその要素を列挙する必要はありません
Lu55 '21

@ Lu55-問題は、コレクション内のアイテムを検索することです。典型的なシナリオは、コレクションが動的であるということです-特定のアイテムを最後に検索してからアイテムが追加または削除された可能性があるため、インデックスは意味がありません(変更されているため)。あなたが持っている場合は、静的に(あなたの計算を実行しながら、変更されないこと)、またはアイテムが削除されることはありませんし、常に最後に追加されたコレクションを、その後Listの状況あなたがある-あなたは、インデックスを覚えることができるので、好ましいです。説明しています。
ToolmakerSteve 2018年

HashSetをソートする必要がある場合は、SortedSetを使用できます。リストよりもはるかに高速です。
live-love

25

以前の答えを説明するために、さまざまなシナリオのいくつかのベンチマークを利用すると思います。

  1. 少数(12〜20)の小さな文字列(長さ5〜10文字)
  2. 多くの(〜10K)小さな文字列
  3. いくつかの長い文字列(長さは200〜1000文字)
  4. 多くの(〜5K)長い文字列
  5. いくつかの整数
  6. 多くの(〜10K)整数

そして、シナリオごとに、表示される値を調べます。

  1. リストの最初( "start"、インデックス0)
  2. リストの先頭近く( "early"、インデックス1)
  3. リストの真ん中( "middle"、index count / 2)
  4. リストの終わり近く( "late"、index count-2)
  5. リストの最後( "end"、インデックスcount-1)

各シナリオの前に、ランダムなサイズのランダムな文字列のリストを生成し、各リストをハッシュセットにフィードしました。各シナリオは基本的に10,000回実行されました。

(テスト疑似コード)

stopwatch.start
for X times
    exists = list.Contains(lookup);
stopwatch.stop

stopwatch.start
for X times
    exists = hashset.Contains(lookup);
stopwatch.stop

出力例

Windows 7、12GB Ram、64ビット、Xeon 2.8GHzでテスト済み

---------- Testing few small strings ------------
Sample items: (16 total)
vgnwaloqf diwfpxbv tdcdc grfch icsjwk
...

Benchmarks:
1: hashset: late -- 100.00 % -- [Elapsed: 0.0018398 sec]
2: hashset: middle -- 104.19 % -- [Elapsed: 0.0019169 sec]
3: hashset: end -- 108.21 % -- [Elapsed: 0.0019908 sec]
4: list: early -- 144.62 % -- [Elapsed: 0.0026607 sec]
5: hashset: start -- 174.32 % -- [Elapsed: 0.0032071 sec]
6: list: middle -- 187.72 % -- [Elapsed: 0.0034536 sec]
7: list: late -- 192.66 % -- [Elapsed: 0.0035446 sec]
8: list: end -- 215.42 % -- [Elapsed: 0.0039633 sec]
9: hashset: early -- 217.95 % -- [Elapsed: 0.0040098 sec]
10: list: start -- 576.55 % -- [Elapsed: 0.0106073 sec]


---------- Testing many small strings ------------
Sample items: (10346 total)
dmnowa yshtrxorj vthjk okrxegip vwpoltck
...

Benchmarks:
1: hashset: end -- 100.00 % -- [Elapsed: 0.0017443 sec]
2: hashset: late -- 102.91 % -- [Elapsed: 0.0017951 sec]
3: hashset: middle -- 106.23 % -- [Elapsed: 0.0018529 sec]
4: list: early -- 107.49 % -- [Elapsed: 0.0018749 sec]
5: list: start -- 126.23 % -- [Elapsed: 0.0022018 sec]
6: hashset: early -- 134.11 % -- [Elapsed: 0.0023393 sec]
7: hashset: start -- 372.09 % -- [Elapsed: 0.0064903 sec]
8: list: middle -- 48,593.79 % -- [Elapsed: 0.8476214 sec]
9: list: end -- 99,020.73 % -- [Elapsed: 1.7272186 sec]
10: list: late -- 99,089.36 % -- [Elapsed: 1.7284155 sec]


---------- Testing few long strings ------------
Sample items: (19 total)
hidfymjyjtffcjmlcaoivbylakmqgoiowbgxpyhnrreodxyleehkhsofjqenyrrtlphbcnvdrbqdvji...
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0018266 sec]
2: list: start -- 115.76 % -- [Elapsed: 0.0021144 sec]
3: list: middle -- 143.44 % -- [Elapsed: 0.0026201 sec]
4: list: late -- 190.05 % -- [Elapsed: 0.0034715 sec]
5: list: end -- 193.78 % -- [Elapsed: 0.0035395 sec]
6: hashset: early -- 215.00 % -- [Elapsed: 0.0039271 sec]
7: hashset: end -- 248.47 % -- [Elapsed: 0.0045386 sec]
8: hashset: start -- 298.04 % -- [Elapsed: 0.005444 sec]
9: hashset: middle -- 325.63 % -- [Elapsed: 0.005948 sec]
10: hashset: late -- 431.62 % -- [Elapsed: 0.0078839 sec]


---------- Testing many long strings ------------
Sample items: (5000 total)
yrpjccgxjbketcpmnvyqvghhlnjblhgimybdygumtijtrwaromwrajlsjhxoselbucqualmhbmwnvnpnm
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0016211 sec]
2: list: start -- 132.73 % -- [Elapsed: 0.0021517 sec]
3: hashset: start -- 231.26 % -- [Elapsed: 0.003749 sec]
4: hashset: end -- 368.74 % -- [Elapsed: 0.0059776 sec]
5: hashset: middle -- 385.50 % -- [Elapsed: 0.0062493 sec]
6: hashset: late -- 406.23 % -- [Elapsed: 0.0065854 sec]
7: hashset: early -- 421.34 % -- [Elapsed: 0.0068304 sec]
8: list: middle -- 18,619.12 % -- [Elapsed: 0.3018345 sec]
9: list: end -- 40,942.82 % -- [Elapsed: 0.663724 sec]
10: list: late -- 41,188.19 % -- [Elapsed: 0.6677017 sec]


---------- Testing few ints ------------
Sample items: (16 total)
7266092 60668895 159021363 216428460 28007724
...

Benchmarks:
1: hashset: early -- 100.00 % -- [Elapsed: 0.0016211 sec]
2: hashset: end -- 100.45 % -- [Elapsed: 0.0016284 sec]
3: list: early -- 101.83 % -- [Elapsed: 0.0016507 sec]
4: hashset: late -- 108.95 % -- [Elapsed: 0.0017662 sec]
5: hashset: middle -- 112.29 % -- [Elapsed: 0.0018204 sec]
6: hashset: start -- 120.33 % -- [Elapsed: 0.0019506 sec]
7: list: late -- 134.45 % -- [Elapsed: 0.0021795 sec]
8: list: start -- 136.43 % -- [Elapsed: 0.0022117 sec]
9: list: end -- 169.77 % -- [Elapsed: 0.0027522 sec]
10: list: middle -- 237.94 % -- [Elapsed: 0.0038573 sec]


---------- Testing many ints ------------
Sample items: (10357 total)
370826556 569127161 101235820 792075135 270823009
...

Benchmarks:
1: list: early -- 100.00 % -- [Elapsed: 0.0015132 sec]
2: hashset: end -- 101.79 % -- [Elapsed: 0.0015403 sec]
3: hashset: early -- 102.08 % -- [Elapsed: 0.0015446 sec]
4: hashset: middle -- 103.21 % -- [Elapsed: 0.0015618 sec]
5: hashset: late -- 104.26 % -- [Elapsed: 0.0015776 sec]
6: list: start -- 126.78 % -- [Elapsed: 0.0019184 sec]
7: hashset: start -- 130.91 % -- [Elapsed: 0.0019809 sec]
8: list: middle -- 16,497.89 % -- [Elapsed: 0.2496461 sec]
9: list: end -- 32,715.52 % -- [Elapsed: 0.4950512 sec]
10: list: late -- 33,698.87 % -- [Elapsed: 0.5099313 sec]

7
面白い。これを実行してくれてありがとう。悲しいことに、私はこれらの議論が不必要なリファクタリングを引き起こすのではないかと思います。うまくいけば、ほとんどの人にとって重要なのは、絶対的な最悪のシナリオでListも、単一のルックアップを実行するのにまだ0.17 ミリ秒しかかからずHashSet、ルックアップ頻度が不条理なレベルに達するまで、代替を必要としないことです。その時までに、リストの使用は通常問題の最も少ないです。
ポールウォール

現在のところ、これは実際の情報ではありません。または、おそらくそれが間違っている可能性があります... 2〜8文字の小さな値を確認しただけです。List / HashSetは10個の値ごとに作成されました... HashSetは30%遅くなります...リストの容量が使用されている場合、差は最大で40%です。リストに容量が指定されておらず、リスト全体を追加する前に各値をチェックする場合にのみ、HashSetが10%速くなります。
マキシム

アイテムの数が4に減ると、最悪のシナリオでも(10%の差で)リストが再び勝ちます。そのため、文字列の小さなコレクション(たとえば、<20)に対してHashSetを使用することはお勧めしません。そして、それはあなたの「いくつかの小さな」テストとは違うものです。
マキシム

1
@Maximは実際に私の結果が「間違っている」とは言えません-それは私のマシンで起こったことです。YMMV。実際、私は新しいWin10 4.0GHz 16GBソリッドステートコンピューターで再度実行(gist.github.com/zaus/014ac9b5a78b267aa1643d63d30c7554)し、同様の結果を得ました。私が知っている重要な点は、検索キーの場所やリストの大きさに関係なく、ハッシュセットのパフォーマンスはより一貫していたのに対し、リストのパフォーマンスは非常に優れたものから300倍以上遅いものまで大きく変動しました。しかし、PaulWallsが最初にコメントしたように、私たちは真剣な#microoptimizationについて話している。
drzaus 2017年

@Maxim for reference:dotnetfiddle.net/5taRDd-気軽に試してみてください。
drzaus 2017年

10

損益分岐は、ハッシュを計算するコストに依存します。ハッシュ計算は取るに足らないか、そうでないかもしれません... :-)損益分岐点について心配する必要がないように支援するSystem.Collections.Specialized.HybridDictionaryクラスが常にあります。


1
また、比較を行うためのコストも考慮する必要があります。Contains(T)の場合、HashSetは比較を実行して、ハッシュの衝突がないことを確認します。正しいリストが見つかる前に、リストが参照するすべての項目で比較を実行します。また、T.GetHashCode()によって生成されたハッシュの分布も考慮する必要があります。これは、常に同じ値を返すので、基本的にHashSetがListと同じことを行うようにするためです。
Martin Brown

6

答えは、いつものように、「あるそれは依存します」です。私はあなたがC#について話しているタグから推測します。

あなたの最善の策は、決定することです

  1. データのセット
  2. 使用要件

そして、いくつかのテストケースを書きます。

また、リストを並べ替える方法(並べ替えられている場合)、どのような比較を行う必要があるか、リスト内の特定のオブジェクトに対して「比較」操作にかかる時間、またはコレクション。

一般に、選択するのに最適なのは、操作しているデータのサイズではなく、データへのアクセス方法です。特定の文字列またはその他のデータに関連付けられた各データがありますか?ハッシュベースのコレクションがおそらく最良でしょう。保存するデータの順序は重要ですか、それともすべてのデータに同時にアクセスする必要がありますか?定期的なリストの方が良いかもしれません。

追加:

もちろん、上記の私のコメントは、「パフォーマンス」がデータアクセスを意味することを前提としています。他に考慮すべきこと:「パフォーマンス」と言うときに何を探していますか?性能個別値ルックアップ?大きな(10000、100000以上)値セットの管理ですか?データ構造をデータで埋めるパフォーマンスですか?データを削除しますか?データの個々のビットにアクセスしていますか?値を置き換えますか?値を繰り返しますか?メモリ使用量?データコピー速度?たとえば、文字列値によってデータにアクセスするが、主なパフォーマンス要件が最小限のメモリ使用である場合、競合する設計上の問題がある可能性があります。


5

ブレークポイントを自動的に検出し、null値を受け入れるHybridDictionaryを使用して、本質的にHashSetと同じにすることができます。


1
これをアイデアに賛成しましたが、今日これを誰も使用しないでください。非ジェネリックにはノーと言ってください。また、辞書はキーと値のマッピングですが、セットはそうではありません。
nawfal 2014年

4

場合によります。正確な答えが本当に重要な場合は、プロファイリングを行って調べてください。セットに特定の数を超える要素が含まれないことが確実な場合は、リストを使用してください。数に制限がない場合は、HashSetを使用します。


3

ハッシュする対象によって異なります。キーが整数の場合、HashSetが高速になる前にアイテムをあまり必要としません。文字列でそれをキーイングしている場合、それは遅くなり、入力文字列に依存します。

きっとあなたはかなり簡単にベンチマークを立てることができるでしょうか?


3

考慮に入れていない1つの要因は、GetHashcode()関数の堅牢性です。完璧なハッシュ関数を使用すると、HashSetの検索パフォーマンスが明らかに向上します。しかし、ハッシュ関数が減少すると、HashSetの検索時間も減少します。


0

多くの要因に依存します...リストの実装、CPUアーキテクチャ、JVM、ループセマンティクス、等しいメソッドの複雑さなど...リストがベンチマーク(1000以上の要素)を効果的にベンチマークするのに十分な大きさになるまでに、ハッシュベースのバイナリルックアップは直線的な検索よりも優れており、違いはそこから拡大するだけです。

お役に立てれば!


1
JVM ...またはCLR :-)
bvgheluwe 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.