Prestaties van removeAll () in een HashSet

1. Overzicht

HashSet is een collectie voor het opbergen van unieke elementen.

In deze tutorial bespreken we de prestaties van de Verwijder alles() methode in de java.util.HashSet klasse.

2. HashSet.removeAll ()

De Verwijder alles methode verwijdert alle elementen die zich in de verzameling:

Set set = new HashSet (); set.add (1); set.add (2); set.add (3); set.add (4); Verzameling verzameling = nieuwe ArrayList (); collection.add (1); collection.add (3); set.removeAll (verzameling); Geheel getal [] actualElements = nieuw geheel getal [set.size ()]; Geheel getal [] verwachtElements = nieuw geheel getal [] {2, 4}; assertArrayEquals (verwachteElements, set.toArray (actualElements)); 

Hierdoor worden elementen 1 en 3 uit de set verwijderd.

3. Interne implementatie en tijdcomplexiteit

De removeAll () methode bepaalt welke kleiner is: de set of de verzameling. Dit wordt gedaan door het aanroepen van de grootte() methode op de set en de collectie.

Als de collectie minder elementen heeft dan de set, dan itereert het over de opgegeven verzameling met de tijdcomplexiteit O (n). Het controleert ook of het element aanwezig is in de set met de tijdcomplexiteit O (1). En als het element aanwezig is, wordt het uit de set verwijderd met behulp van de verwijderen() methode van de set, die weer een tijdcomplexiteit heeft van O (1). Zo de totale tijdcomplexiteit is O (n).

Als de set minder elementen heeft dan de collectie, dan itereert het over deze set met behulp van O (n). Vervolgens controleert het of elk element aanwezig is in de verzameling door zijn bevat () methode. En als zo'n element aanwezig is, wordt het element uit de set verwijderd. Dit hangt dus af van de tijdcomplexiteit van de bevat () methode.

Als de verzameling nu een ArrayList, de tijdcomplexiteit van de bevat () methode is O (m). Zo totale tijdcomplexiteit om alle elementen in het ArrayList uit de set is O (n * m).

Als de collectie opnieuw is HashSet, de tijdcomplexiteit van de bevat () methode is O (1). Zo totale tijdcomplexiteit om alle elementen in het HashSet uit de set is O (n).

4. Prestaties

Laten we een eenvoudige JMH-benchmarktest schrijven om het prestatieverschil tussen de bovenstaande 3 gevallen te zien.

Voor het eerste geval initialiseren we de set en verzameling, waarbij we meer elementen in de set hebben dan de verzameling. In het tweede geval initialiseren we de set en de verzameling, waarbij we meer elementen in de verzameling hebben dan de set. En in het derde geval initialiseren we 2 sets, waarbij we de 2e set hebben met meer elementen dan de 1e:

@BenchmarkMode (Mode.AverageTime) @OutputTimeUnit (TimeUnit.NANOSECONDS) @Warmup (iteraties = 5) openbare klasse HashSetBenchmark {@State (Scope.Thread) openbare statische klasse MyState {privé Set employeeSet1 = nieuwe HashSet (); private List employeeList1 = nieuwe ArrayList (); private Set employeeSet2 = nieuwe HashSet (); private List employeeList2 = nieuwe ArrayList (); private Set employeeSet3 = nieuwe HashSet (); private Set employeeSet4 = nieuwe HashSet (); privé lange set1Size = 60000; privé lange lijst1Size = 50000; privé lange set2Size = 50000; privé lange lijst2Size = 60000; privé lange set3Size = 50000; privé lange set4Size = 60000; @Setup (Level.Trial) public void setUp () {// sets vullen}}}

Daarna voegen we onze benchmarktests toe:

@Benchmark openbare boolean gegeven_SizeOfHashsetGreaterThanSizeOfCollection_whenRemoveAllFromHashSet_thenGoodPerformance (MyState staat) {terugkeer state.employeeSet1.removeAll (state.employeeList1); } @Benchmark openbare boolean gegeven_SizeOfHashsetSmallerThanSizeOfCollection_whenRemoveAllFromHashSet_thenBadPerformance (MyState staat) {terugkeer state.employeeSet2.removeAll (state.employeeList2); } @Benchmark openbare boolean gegeven_SizeOfHashsetSmallerThanSizeOfAnotherHashSet_whenRemoveAllFromHashSet_thenGoodPerformance (MyState staat) {terugkeer state.employeeSet3.removeAll (state.employeeSet4); }

En hier zijn de resultaten:

Benchmark-modus Cnt Score Fout Eenheden HashSetBenchmark.testHashSetSizeGreaterThanCollection avgt 20 2700457.099 ± 475673.379 ns / op HashSetBenchmark.testHashSetSmallerThanCollection gem. 20 31522676649.950 ± 355683.

We kunnen de HashSet.removeAll () presteert behoorlijk slecht als de HashSet heeft minder elementen dan de Verzameling, die als argument wordt doorgegeven aan de Verwijder alles() methode. Maar wanneer de andere collectie er weer is HashSet, dan is de prestatie goed.

5. Conclusie

In dit artikel zagen we de uitvoering van Verwijder alles() in HashSet. Heeft de set minder elementen dan de collectie, dan is de uitvoering van Verwijder alles() hangt af van de tijdcomplexiteit van de bevat () methode van de collectie.

Zoals gewoonlijk is de volledige code voor dit artikel beschikbaar op GitHub.