Tengo que ejecutar esta línea de cose varios millones de veces, me pregunto si hay una manera de optimizarlo (tal vez precomputen algo?).
a.contains(b) || b.contains(a)
Gracias
edit: el código ejecutado por el método ya contiene controles para a.length <b.length.
public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
byte first = str[0];
int max = (valueCount - strCount);
for (int i = fromIndex; i <= max; i++) {
[...]
}
return -1;
}
Según tengo entendido la tarea, usted tiene que comprobar si a
contiene b
o viceversa para cada par de a
y b
de un conjunto de cerca de 35 millones de palabras. Eso es un montón de pares de comprobar.
Usted debe ser capaz de reducir la búsqueda considerable por precomputen que n-gramos contiene una palabra: si a
contiene algún n-gram, entonces b
tiene que contener el mismo n-gram si b
contiene a
. Por ejemplo, podría calcular previamente todos los trigramas que cada palabra de la lista contiene, y al mismo tiempo todas las palabras que contienen un trigrama dado, entonces usted puede simplemente buscar las palabras en estos diccionarios y con algunas operaciones de conjuntos consiguen un pequeño conjunto de candidatos para poder controlar eficazmente.
En pseudo-código:
- seleccionar un tamaño para los n-gramas (véase a continuación)
- Iniciar una
Map<String, Set<String>> ngram_to_word
- la primera iteración: para cada palabra
a
en su conjunto de datos- Iterar todos los n-gramas (por ejemplo, utilizando algún tipo de ventana deslizante) de
a
- para cada uno, añadir
a
a los conjuntos de palabras que contienen esos n-gramas enngrams_to_words
- Iterar todos los n-gramas (por ejemplo, utilizando algún tipo de ventana deslizante) de
- segunda iteración: para cada palabra
a
en su conjunto de datos- de nuevo obtener todos los n-gramas
a
contiene - para cada uno de aquellos, obtener el conjunto de palabras que contiene que el n-gramo de
ngrams_to_words
- obtener la intersección de los conjuntos de palabras
- para cada palabra
b
en esa intersección que contiene todos los n-gramas quea
contiene (pero tal vez en un orden diferente o cantidad), adecuadamente comprobar sib
contienea
- de nuevo obtener todos los n-gramas
Dependiendo del número de letras en los n-gramas (por ejemplo bigramas, trigramas, ...), que será más caro para pre-cálculo, tanto en el tiempo y en el espacio, pero el efecto también será mayor. En el caso más sencillo, incluso se podría simplemente calcular previamente que las palabras contienen una letra dada (es decir, "1-gramas"); que debe ser rápido y ya considerable reducir el número de palabras para comprobar. Por supuesto, los n-gramas no deberían ser más corta que la más corta de las palabras en el conjunto de datos, sino que incluso se pueden utilizar dos longitud de n-gramas, por ejemplo, el uso de dos mapas letter_to_words
y trigrams_to_words
.