Java: optimiza el hashset para la detección de duplicados a gran escala

Estoy trabajando en un proyecto donde estoy procesando muchos tweets; El objetivo es eliminar los duplicados a medida que los procese. Tengo las ID de tweets, que vienen como cadenas del formato"166471306949304320"

He estado usando unHashSet<String> Para esto, que funciona bien por un tiempo. Pero para cuando llego a alrededor de 10 millones de artículos, estoy drásticamente atascado y eventualmente recibo un error de GC, presumiblemente por el refrito. Intenté definir un mejor tamaño / carga con

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

y eso le permite ir un poco más lejos, pero sigue siendo extremadamente lento (alrededor de 10 millones tarda 3 veces más en procesarse). ¿Cómo puedo optimizar esto? Dado que tengo una idea aproximada de cuántos elementos deberían estar en el conjunto para el final (en este caso, alrededor de 20-22 millones), debería crear un HashSet que se reinicie solo dos o tres veces, o el costo general para tal ¿Establecer incurrir en demasiadas penalizaciones de tiempo? ¿Funcionarían mejor las cosas si no estuviera usando una cadena o si definiera una función HashCode diferente (que, en este caso de una instancia particular de una cadena, no estoy seguro de cómo hacerlo)? Esta parte del código de implementación está abajo.

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; 
}

SOLUCIÓN

Gracias a tus recomendaciones, lo resolví. El problema fue la cantidad de memoria requerida para las representaciones hash; primero,HashSet<String> era simplemente enorme y fuera de lugar porque laString.hashCode() Es exorbitante para esta escala. Luego probé un Trie, pero se estrelló en poco más de 1 millón de entradas; La reasignación de las matrices fue problemática. Usé unHashSet<Long> para un mejor efecto y casi lo hizo, pero la velocidad decayó y finalmente se estrelló en la última etapa del procesamiento (alrededor de 19 millones). La solución vino saliendo de la biblioteca estándar y usandoTrove. Terminó 22 millones de registros unos minutos más rápido que no verificando duplicados en absoluto. La implementación final fue simple, y se veía así:

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; 
    }

Respuestas a la pregunta(3)

Su respuesta a la pregunta