因此,我试图尽可能地优化我的代码。下面的代码过去运行在5秒左右,但是我设法将它减少到了大约1,4秒,但是仍然不够。我能做些什么来优化这段代码呢?(也许我应该提一下,我谈到的时候是在aux最后有170080个键的时候)。
public List<String> getProdutosMaisCompradosQuantidade(int filial, int X){
Map<String, ProdutoFilial> aux;
if(filial==0) {
aux = new HashMap<>(ValoresFixos.CATALOGO_PRODUTOS_TAMANHO_INICIAL);
filiais.stream()
.forEach( (f) -> {
Map<String, ProdutoFilial> aux2 = f.getMapProdutosDadosFilialSemEncapsulamento();
aux2.forEach((k,t) -> {
if(t.getQuantidade()>0){
if(aux.containsKey(k)) aux.get(k).atualizarValores(t);
else aux.put(k,t);
}
});
});
}
else aux = filiais.get(filial-1).getMapProdutosDadosFilialSemEncapsulamento();
List<String> list =
aux
.entrySet()
.stream()
.sorted(new ComparadorProdutoQuantidade())
.map(e -> e.getKey()+"\n | o Quantidade: "+e.getValue().getQuantidade()+"; Comprado por "+e.getValue().getNumeroCompradores()+" Clientes Distintos")
.collect(Collectors.toList());
if(X>list.size()) X = list.size();
list.subList(X, list.size()).clear();
return list;
}我在这里使用的所有方法几乎都是O(1)复杂度,比较器也不太费钱,所以这不应该是问题所在,有什么我可能不知道的东西可以帮助我优化这个流操作?也许我使用的entrySet可以避免.?因为这可能是这里最昂贵的手术..。
EDIT1:也许我应该解释一下这种方法背后的想法。它的主要目的是对地图进行排序,并返回一个带有排序键的列表(键也被修改了,但这不是主要目的)。
发布于 2016-06-08 19:06:26
您可以尝试将forEach语句替换为map和collect,如Java 8-转换列表的最佳方法: map还是foreach?中所述
然后,如果使用并行流可以提高性能,则可以尝试。
可以用Stream替换创建aux映射的语句(使用Collectors.toMap和/或Collectors.groupingBy)。这被认为比使用forEach更干净,后者使用有状态操作。
关于如何实现https://stackoverflow.com/search?q=groupingBy+[java-stream]或https://stackoverflow.com/search?q=toMap+[java-stream],已经有很多问题了。
如果您需要更快的解决方案(更改较少),可以尝试用Map替换ConcurrentHashMap并使用并行流。您可以使用它的合并函数使计算可并行化。
https://stackoverflow.com/questions/37709644
复制相似问题