java - 对于大数据量,什么数据结构更快?

标签 java arrays spring data-structures

我正在开发一个关于 Spring Boot 的项目,并且必须处理存储在 Solr 中的大量信息。我必须将所有存储的图像与用户输入的图像进行比较并建立相似性。我一开始使用图像的 LinkedList,现在使用数组和 LinkedList,但速度也很慢,有时甚至不起作用。我说的是我必须处理的 11 000 000 张图像。这是我的代码:

 public LinkedList<Imagen> comparar(Imagen[] lista, Imagen imagen) throws NullPointerException {
    LinkedList<Imagen> resultado = new LinkedList<>();
    for (int i = 0; i < lista.length; i++) {
        if (lista[i].getFacesDetectedQuantity() == imagen.getFacesDetectedQuantity()) {
            lista[i].setSimilitud(3);
        }
        if (herramientas.rangoHue(imagen.getPredominantColor_hue()).equals(herramientas.rangoHue(lista[i].getPredominantColor_hue()))) {
            lista[i].setSimilitud(3);
        }
        if (lista[i].isTransparency() == imagen.isTransparency()) {
            lista[i].setSimilitud(4);
        }
        if (analizar.compareFeature(herramientas.image64ToImage(lista[i].getLarge_thumbnail()), herramientas.image64ToImage(imagen.getLarge_thumbnail())) > 400) {
            lista[i].setSimilitud(3);
        }
        if (analizar.compare_histogram(herramientas.image64ToImage(lista[i].getLarge_thumbnail()), herramientas.image64ToImage(imagen.getLarge_thumbnail())) > 90) {
            lista[i].setSimilitud(3);
        }
        if (lista[i].getSimilitud() > 7) {
            resultado.add(lista[i]);
        }
    }
    return ordenarLista(resultado);
}


public LinkedList<Imagen> ordenarLista(LinkedList<Imagen> lista) {
    LinkedList<Imagen> resultado = new LinkedList<>();
    for (int y = 0; y < lista.size(); y++) {
        Imagen imagen = lista.get(0);
        int posicion = 0;
        for (int x = 0; x < lista.size(); x++) {
            if (lista.get(x).getSimilitud() > imagen.getSimilitud()) {
                imagen = lista.get(x);
                posicion = x;
            }
        }
        resultado.add(imagen);
        lista.remove(posicion);
    }
    return resultado;
}

知道我可以使用什么数据结构来使过程更快。我也在考虑在线程内创建每个比较 if 但也不知道如何做到这一点。谷歌搜索了很多,却什么也没找到。抱歉我的英语不好,谢谢!

我解决了使用 ordenarLista() 方法排序的问题,只是忽略它,并在返回列表之前将此代码添加到我的 comparar() 方法中。

Collections.sort(resultado, new Comparator<Imagen>() {

            @Override
            public int compare(Imagen image1, Imagen image2) {
                return image2.getSimilitud() - image1.getSimilitud();
            }
        });

仍在研究我的算法!

最佳答案

一般来说,在尝试随机优化任何部分之前,请使用 JVisualVM 等监控工具来准确检测昂贵的调用。你必须把努力放在正确的地方。

此外,跟踪第一次大处理(在 ordenarLista() 之前)和第二次大处理(ordenarLista())所花费的时间也应该会有所帮助。

实际上,我注意到一些事情:

1) 很可能是一个问题:comparar() 执行许多重复处理,这些处理在 CPU 方面可能会很昂贵。

看看这两个调用:

if (analizar.compareFeature(herramientas.image64ToImage(lista[i].getLarge_thumbnail()), herramientas.image64ToImage(imagen.getLarge_thumbnail())) > 400) {
    lista[i].setSimilitud(3);
}
if (analizar.compare_histogram(herramientas.image64ToImage(lista[i].getLarge_thumbnail()), herramientas.image64ToImage(imagen.getLarge_thumbnail())) > 90) {
    lista[i].setSimilitud(3);
}

例如,您在每次迭代时调用 4 次 herramientas.image64ToImage()

这应该在循环之前执行一次:

herramientas.image64ToImage(imagen.getLarge_thumbnail())

但是你在循环中执行了数百万次。 只需将结果存储在循环之前的变量中并在循环中使用即可。 同样的事情:

herramientas.rangoHue(imagen.getPredominantColor_hue()

所有仅依赖于 Imagen imagen 参数的计算都应该在循环之前进行计算,并且永远不要进行计算,以节省数百万次。

2) ordenarLista() 似乎有问题:您在此处硬编码了第一个索引:

Imagen imagen = lista.get(0);

3) ordenarLista() 可能会迭代多次:

lista.size() + lista.size() 
+
lista.size()-1 + lista.size() 
+
lista.size()-2 + lista.size() 
+
...
+ 1 * lista.size() 

想象一下,其中有 1.000.000 元素:

1.000.000 + 1.000.000 
+
999.999  + 1.000.000 
+
999.998  + 1.000.000 
+
...
+ 
1 + 1.000.000 

它赚了数百万......

关于java - 对于大数据量,什么数据结构更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49398442/

相关文章:

spring - 手动更改 Multi-Tenancy session

java - 如何在 Liferay serveResource(-, -) 方法中从 AJAX 请求下载文件

java - Android - 在我的 onStop() 方法中写入文件使我的应用程序崩溃

java - 用于 Spring Boot 获取请求的 mongo uri

javascript - 检查 jQuery 或 Javascript 中哈希数组中某些值的存在

java - Spring Boot 如何使用数据库而不是 application.properties

java - 我应该使用 ArithmeticException 还是 IllegalArgumentException ,有什么区别?

php - 读取 CSV,但创建包含行的单个数组,而不是多维数组?

php - PHP中遍历数组是什么意思?

java - Spring Batch 中 map 的项目阅读器?