web-dev-qa-db-ja.com

ハッシュセットと配列リストのパフォーマンス

さまざまなモジュールのデータを含むCSVファイルのセットを単純にループするメソッドを実装しました。これにより、「moduleName」がhashSetに追加されます。 (以下に示すコード)

HashSetを使用しました。これは、ArrayListの代わりに重複が挿入されないことを保証するためです。

ハッシュセットを使用すると、配列リストよりもパフォーマンスが向上すると思います。私はそれを述べることで正しいですか?

また、誰かが私に説明できます:

  1. 使用されている場合、各データ構造のパフォーマンスを動作させる方法は?
  2. Big-O表記を使用した複雑さは何ですか?

    HashSet<String> modulesUploaded = new HashSet<String>();
    
    for (File f: marksheetFiles){
        try {
            csvFileReader = new CSVFileReader(f);
            csvReader = csvFileReader.readFile();
            csvReader.readHeaders();
    
            while(csvReader.readRecord()){
                String moduleName = csvReader.get("Module");
    
                if (!moduleName.isEmpty()){
                    modulesUploaded.add(moduleName);
                }
            }
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        csvReader.close();
    }
    return modulesUploaded; 
    

    }

35
user1339335

私の実験 は、HashSetArrayListよりも高速であることを示しています。

完全な結果表

| Boost  |  Collection Size  |
|  2x    |       3 elements  |
|  3x    |      10 elements  |
|  6x    |      50 elements  |
|  12x   |     200 elements  |  <= proportion 532-12 vs 10.000-200 elements
|  532x  |  10.000 elements  |  <= shows linear lookup growth for the ArrayList
45
Andrey Chaschev

これらは完全に異なるクラスなので、質問は次のとおりです。どのような動作が必要ですか?

HashSetは、重複がないことを確認し、O(1) contains()メソッドを提供しますが、順序は保持しません。
ArrayListは重複がないことを保証しません。contains()はO(n)ですが、エントリの順序を制御できます。

25
biziclop

ハッシュセットを使用すると、配列リストよりもパフォーマンスが向上すると思います。私はそれを述べることで正しいですか?

多くの(意味が何であれ)エントリがあります。ただし、データサイズが小さい場合、生の線形検索はハッシュよりも高速になる可能性があります。損益分岐点がどこにあるのかを正確に測定する必要があります。私の直感では、要素が10個未満の場合、線形ルックアップはおそらく高速になります。 100を超える要素を使用したハッシュはおそらく高速ですが、それは単なる私の気持ちです...

HashSetからのルックアップは、要素のhashCode実装が正しければ、一定時間O(1)です。リストからの線形ルックアップは線形時間O(n)です。

20
Joonas Pulakka

データ構造の使用法に依存します。

データをHashSetに格納していますが、ストレージの場合、HashSetArrayListよりも優れています(重複エントリが必要ないため)。しかし、単に保管することは通常の意図ではありません。

保存されたデータをどのように読み取り、処理するかによって異なります。シーケンシャルアクセスまたはランダムインデックスベースのアクセスが必要な場合は、ArrayListの方が適しています。または、順序が重要でない場合は、HashSetの方が優れています。

順序が重要で、多くの変更(追加と削除)を行いたい場合は、LinkedListの方が適しています。

特定の要素にアクセスする場合、HashSetはO(1)のような時間の複雑さを持ち、ArrayListを使用した場合、あなた自身が指摘したようにO(N)になります。リストをiterateして、要素が存在しないかどうかを確認します。

5
nits.kk