2
respostas

Problema em Processamento Grande

Desenvolvi um app com a ajuda deste curso e estou enfrentando um problema talvez simples de resolver. Tenho um App que comunica com uma API para consultar em 2 tabelas do meu banco Oracle; No momento em que estou com as 2 listas das tabelas, eu preciso criar uma terceira lista com determinados critérios com base nas duas que eu já havia armazenado. Para isso eu fiz uma cadeia de For que percorre uma lista percorrendo a outra como no Exemplo Abaixo:

List<LoteSAP> lotes = await getApi.consultarLotes();
List<Ferramenta> ferramentas = await getApi.consultarFerramentas();
List<Ferramenta> listaAux = [];

      for (LoteSap lote in lotes) {
        for (Ferramenta ferr in ferramentas) {
          if (lote.codMaterial == ferr.codigo && lote.centro == almox.centro.toString() && lote.deposito == almox.deposito) {
            if (!listaAux.contains(ferr)) {
              listaAux.add(
                Ferramenta(
                  codigo: ferr.codigo,
                  descricao: ferr.descricao,
                  estoqueUsado: ferr.estoqueUsado,
                  loteSAP: lote.lote,
                  unidade: ferr.unidade,
                  quantidade: ferr.quantidade,
                  justificativa: ferr.justificativa,
                  selecao: ferr.selecao,
                ),
              );
            }
          }
        }
      }

Meu problema é que essas duas listas tem um pouco mais de 30k de registros, quando o processo chega no For() o app trava meu CircularProgressIndicator() por aproximadamente 1 min, eu gostaria de saber se existe alguma solução, será que talvez a melhor forma seria atrelar essas listas enquanto ainda estão na API e enviar somente a terceira para o App?

2 respostas

Fala Reginaldo, de boa ?

Cara acho que a complexidade ciclomática desse código tá bem alta e isso explicaria o motivo da demora.

Não sei se é o caso de você fazer um filtro ou na camada do flutter ou na camada da api(recomendado) para que traga somente os registros do jeito que tu quer

E aí Reginaldo, tudo bem? Cara, creio que tu consigas até melhorar o processamento desse código utilizando um Future.wait para as requisicões assíncronas e ao invés de usar um aninhamento de for, talvez faca mais sentido usar algo do gênero

    final List<Ferramenta> listaAux = ferramentas.where(
        (ferr) => lotes.any(
            (lote) => lote.codMaterial == ferr.codigo && lote.centro == almox.centro && lote.deposito == almox.deposito,
        ),
    ).toList();

Pq dentro dos 2 for e 2 ifs você parece estar apenas criando um nova instância de Ferramenta outra coisa, dentro do segundo if, há um .toString, que caso seu almox.centro seja um tipo primitivo String, não é necessário.

Caso opte pelo Future.wait, terá que criar um array de Futures<dynamic>, visto que um será do tipo List<Ferramenta> e outro List<LoteSAP>

Caso tenha ficado confuso o que eu comentei acima, pode responder aqui, ou perguntar via Discord (Bryan Feiten#2615)

#Editado#

Não vi que você usa o lote para reformular a instância de Ferramenta... Nesse caso, eu sugiro apenas que você inverta os fors pois para cada lote você está rodando todas as ferramentas, isso gera itens repetidos, e você corrige isso com o segundo if, o problema é que o segundo if faz uma nova interacão com todas as ferramentas verificando um objeto complexo. Para melhorar isso, apenas invertendo os fors você já garante que ele pegue uma ferramenta e verifique todos os lotes, e não o contrário. Caso o lote seja único, você pode ainda remover ele da lista, garantindo uma próxima interacão menor.

OBS::: Note que estou contando que você resolva isso no app. Caso tenha a possibilidade, seria mais interessante resolver em um endpoint próprio (pela quantia de dados), ainda mais por ter em vista que você já está forcando seu back a fazer esse processamento de get das 2 listas