Jon Skeet kısa süre önce blogunda ilginç bir programlama konusu gündeme getirdi: "Soyutlamamda bir boşluk var sevgili Liza, sevgili Liza" (vurgu eklenmiştir):
HashSetAslında bir setim var . Bazı öğeleri ondan kaldırmak istiyorum… ve öğelerin çoğu pek mevcut olmayabilir. Aslında, bizim test örneğimizde, "kaldırma" koleksiyonundaki hiçbir öğe orijinal sette olmayacak. Bu sesler - aslında ve bir son derece kolay koduna -. SonuçtaSet<T>.removeAllbize yardım etmeliyiz , değil mi?Komut satırında "kaynak" kümesinin boyutunu ve "kaldırma" koleksiyonunun boyutunu belirleyip ikisini de oluşturuyoruz. Kaynak kümesi yalnızca negatif olmayan tam sayıları içerir; kaldırma kümesi yalnızca negatif tamsayılar içerir. Kullanarak tüm öğeleri kaldırmanın ne kadar sürdüğünü ölçüyoruz
System.currentTimeMillis(), ki bu dünyanın en doğru kronometresi değil ama göreceğiniz gibi bu durumda fazlasıyla yeterli. İşte kod:import java.util.*; public class Test { public static void main(String[] args) { int sourceSize = Integer.parseInt(args[0]); int removalsSize = Integer.parseInt(args[1]); Set<Integer> source = new HashSet<Integer>(); Collection<Integer> removals = new ArrayList<Integer>(); for (int i = 0; i < sourceSize; i++) { source.add(i); } for (int i = 1; i <= removalsSize; i++) { removals.add(-i); } long start = System.currentTimeMillis(); source.removeAll(removals); long end = System.currentTimeMillis(); System.out.println("Time taken: " + (end - start) + "ms"); } }Kolay bir iş vererek başlayalım: 100 öğelik bir kaynak kümesi ve kaldırılacak 100 öğe:
c:UsersJonTest>java Test 100 100 Time taken: 1msTamam, yani yavaş olmasını beklemiyorduk… açıkça işleri biraz hızlandırabiliriz. Kaldırılacak bir milyon öğe ve 300.000 öğe kaynağı nasıl olur?
c:UsersJonTest>java Test 1000000 300000 Time taken: 38msHmm. Yine de oldukça hızlı görünüyor. Şimdi biraz acımasız olduğumu hissediyorum, tüm bunları kaldırmasını istedim. Bunu biraz daha kolaylaştıralım - 300.000 kaynak öğe ve 300.000 kaldırma:
c:UsersJonTest>java Test 300000 300000 Time taken: 178131msAffedersiniz? Yaklaşık üç dakika mı? Eyvah! Elbette , 38 ms'de yönettiğimizden daha küçük bir koleksiyondaki öğeleri çıkarmak daha kolay olmalı ?
Birisi bunun neden olduğunu açıklayabilir mi? HashSet<T>.removeAllYöntem neden bu kadar yavaş?