Quindi originariamente avevo questo codice:
import java.util.*;
public class sandbox {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
for (int i = 0; i < 100_000; i++) {
hashSet.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < 100_000; i++) {
for (Integer val : hashSet) {
if (val != -1) break;
}
hashSet.remove(i);
}
System.out.println("time: " + (System.currentTimeMillis() - start));
}
}
Ci vogliono circa 4 secondi per eseguire i loop nidificati sul mio computer e non capisco perché ci sia voluto così tanto tempo. Il ciclo esterno viene eseguito 100.000 volte, il ciclo interno interno dovrebbe essere eseguito 1 volta (poiché qualsiasi valore di hashSet non sarà mai -1) e la rimozione di un elemento da un HashSet è O (1), quindi dovrebbero esserci circa 200.000 operazioni. Se in genere ci sono 100.000.000 di operazioni in un secondo, come mai il mio codice impiega 4 secondi per essere eseguito?
Inoltre, se la riga hashSet.remove(i);
viene commentata, il codice richiede solo 16ms. Se il ciclo interno interno viene commentato (ma non hashSet.remove(i);
), il codice richiede solo 8 ms.
for val
ciclo sia la cosa che richiede tempo. Il remove
è ancora molto veloce. Una sorta di overhead che imposta un nuovo iteratore dopo che il set è stato modificato ...?
for val
ciclo è lento. Tuttavia, si noti che il ciclo non è affatto necessario. Se si desidera verificare se ci sono valori diversi da -1 nel set, sarebbe molto più efficiente verificare hashSet.size() > 1 || !hashSet.contains(-1)
.