He encontrado un problema que no puedo encontrar una solución. Estoy usando un HashSet para almacenar valores. Los valores que almaceno son del tipo personalizado Cycles donde he reemplazado el HashCode y es igual a lo siguiente para asegurarme de que el código lento o los métodos iguales no compliquen el rendimiento lento También he establecido la capacidad inicial del hashset para 10.000.000HashSet. rendimiento lento en el conjunto grande
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (cycleId^(cycleId >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cycle other = (Cycle) obj;
if (cycleId != other.cycleId)
return false;
return true;
}
Después de los primeros 1.500.000 primeros valores cuando trato de añadir un nuevo valor (con el método Add de la clase HashSet) el programa es muy lento. Eventualmente voy a tener la excepción java de memoria (Excepción en el hilo "Thread-0" java.lang.OutOfMemoryError: espacio de pila de Java) antes de que los valores almacenados lleguen al 1.600.000
El IDE que uso es Eclipse. Así que el siguiente paso fue aumentar el tamaño del almacenamiento dinámico de JVM del valor predeterminado a 1 giga (usando los comandos Xmx1000M y Xms1000M) Ahora el elipse comienza con 10 veces más memoria disponible (puedo ver que en la parte inferior derecha donde está el montón total) Se muestra la memoria de tamaño y la memoria utilizada) pero, una vez más, tengo el mismo rendimiento "lento" y el mismo error de memoria EN LOS MISMOS VALORES que antes (después de los 1.500.000 y antes de 1.600.000), lo cual es muy extraño.
¿Alguien tiene una idea de lo que podría ser el problema?
Gracias de antemano
¿Qué es cycleId exactamente? Si se trata de una identificación como identidad y, por lo tanto, única para los ciclos, simplemente devuelva cycleId como código hash. Si no es un Entero, entonces tome hashCode de qué tipo es. Si es un bit de 64 bits y el ID está comenzando desde 0 (con una distribución par o la mayoría en los 32 bits inferiores), entonces empújelo a int. –
@lasseespeholt, ¿por qué? ¡Entonces el hashcode solo dependería de los 32 bits más bajos del largo! Usar * todos * los bits es el camino a seguir. ¡Imagine qué tipo de desastre ocurriría si String.hashCode() utilizara solo los últimos dos caracteres para hacer un 32 hashCode! –
¿Ha perfilado su programa para verificar que es el 'HashSet' el que está ralentizando las cosas? –