web-dev-qa-db-fra.com

Performances de Hash Set et Array List

J'ai mis en œuvre une méthode qui fait simplement une boucle autour d'un ensemble de fichiers CSV qui contiennent des données sur un certain nombre de modules différents. Cela ajoute ensuite le 'moduleName' dans un hashSet. (Code indiqué ci-dessous)

J'ai utilisé un hashSet car il garantit qu'aucun doublon n'est inséré à la place d'un ArrayList qui devrait utiliser la méthode contain () et parcourir la liste pour vérifier s'il est déjà là.

Je crois que l'utilisation de l'ensemble de hachage a de meilleures performances qu'une liste de tableaux. Ai-je raison de dire cela?

Quelqu'un peut-il aussi m'expliquer:

  1. Comment travailler les performances de chaque structure de données si elle est utilisée?
  2. Quelle est la complexité de l'utilisation de la notation 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

Mon expérience montre que HashSet est plus rapide qu'un ArrayList à partir de collections de 3 éléments inclusivement.

Un tableau de résultats complet

| 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

Ce sont des classes complètement différentes, donc la question est: quel type de comportement voulez-vous?

HashSet garantit qu'il n'y a pas de doublons, vous donne une méthode O(1) contains() mais ne préserve pas l'ordre.
ArrayList ne garantit pas qu'il n'y a pas de doublons, contains() est O(n) mais vous pouvez contrôler l'ordre des entrées .

25
biziclop

Je crois que l'utilisation de l'ensemble de hachage a de meilleures performances qu'une liste de tableaux. Ai-je raison de dire cela?

Avec de nombreuses entrées (quoi que cela signifie), oui. Avec de petites tailles de données, la recherche linéaire brute pourrait cependant être plus rapide que le hachage. Où se situe exactement le seuil de rentabilité, il suffit de mesurer. Mon intuition est qu'avec moins de 10 éléments, la recherche linéaire est probablement plus rapide; avec plus de 100 éléments, le hachage est probablement plus rapide, mais c'est juste mon sentiment ...

La recherche à partir d'un HashSet est à temps constant, O (1), à condition que l'implémentation hashCode des éléments soit saine. La recherche linéaire à partir d'une liste est un temps linéaire, O (n).

20
Joonas Pulakka

Cela dépend de l'utilisation de la structure de données.

Vous stockez les données dans HashSet, et pour votre cas pour le stockage HashSet est meilleur que ArrayList (car vous ne voulez pas des entrées en double). Mais le simple stockage n'est pas l'intention habituelle.

Cela dépend de la façon dont vous souhaitez lire et traiter les données stockées. Si vous voulez un accès séquentiel ou un accès aléatoire basé sur un index, alors ArrayList est mieux ou si la commande n'a pas d'importance alors HashSet est mieux.

Si la commande est importante mais que vous voulez faire beaucoup de modifications (ajouts et suppressions), la LinkedList est meilleure.

Pour accéder à un élément particulier, HashSet aura une complexité temporelle comme O (1) et si vous auriez utilisé ArrayList cela aurait été O (N) comme vous l'avez vous-même souligné, vous devriez iterate à travers la liste et voir si l'élément n'est pas présent.

5
nits.kk