Java: optymalizacja skrótu do wykrywania duplikatów na dużą skalę

Pracuję nad projektem, w którym przetwarzam wiele tweetów; celem jest usunięcie duplikatów podczas ich przetwarzania. Mam tweety ID, które pojawiają się jako ciągi formatu"166471306949304320"

UżywamHashSet<String> za to, co działa przez chwilę. Ale zanim dotrę do około 10 milionów pozycji, drastycznie się ugrzęzłem i ostatecznie otrzymuję błąd GC, prawdopodobnie z powodu ponownego wymieszania. Próbowałem zdefiniować lepszy rozmiar / obciążenie

tweetids = new HashSet<String>(220000,0.80F);

i to pozwala na trochę dalej, ale wciąż jest niezwykle powolne (około 10 milionów trwa 3 razy dłużej). Jak mogę to zoptymalizować? Biorąc pod uwagę, że mam przybliżone wyobrażenie o tym, ile elementów powinno być w zestawie do końca (w tym przypadku około 20-22 milionów), powinienem utworzyć zestaw HashSet, który zmienia tylko dwa lub trzy razy, czy też koszty ogólne dla takiego ustawić zbyt wiele kar za czas? Czy rzeczy działałyby lepiej, jeśli nie używałbym ciągu znaków lub jeśli zdefiniowałbym inną funkcję HashCode (która w tym przypadku konkretnego wystąpienia ciągu znaków nie jest pewna, jak to zrobić)? Ta część kodu implementacji znajduje się poniżej.

tweetids = new HashSet<String>(220000,0.80F); // in constructor
duplicates = 0;
...
// In loop: For(each tweet)
String twid = (String) tweet_twitter_data.get("id");
// Check that we have not processed this tweet already
if (!(tweetids.add(twid))){
    duplicates++;
    continue; 
}

ROZWIĄZANIE

Dzięki twoim zaleceniom rozwiązałem to. Problem polegał na ilości pamięci wymaganej do reprezentacji skrótu; pierwszy,HashSet<String> był po prostu ogromny i niesłuszny, ponieważString.hashCode() jest wygórowana dla tej skali. Następnie spróbowałem Trie, ale rozbił się na ponad 1 milionie wpisów; ponowne przydzielenie tablic było problematyczne. UżyłemHashSet<Long> aby uzyskać lepszy efekt i prawie się udało, ale prędkość spadła i ostatecznie rozbił się na ostatnim etapie przetwarzania (około 19 milionów). Rozwiązaniem było odejście od standardowej biblioteki i korzystanie z niejTrove. Skończył 22 miliony rekordów kilka minut szybciej niż nie sprawdzanie duplikatów w ogóle. Ostateczna implementacja była prosta i wyglądała tak:

import gnu.trove.set.hash.TLongHashSet;
...
    TLongHashSet tweetids; // class variable
... 
    tweetids = new TLongHashSet(23000000,0.80F); // in constructor
...
    // inside for(each record)
    String twid = (String) tweet_twitter_data.get("id");
    if (!(tweetids.add(Long.parseLong(twid)))) {
        duplicates++;
        continue; 
    }

questionAnswers(3)

yourAnswerToTheQuestion