Otimização de código parte II

Olá pessoal, mais uma da série de otimização de código:

Tenho um algoritmo muito grande que com um corpus grande demora 3987 milisegundos. Aceito sugestões para ganhar performance, la vái:

public TDMElements getMatrix(FileInputStream f) {
        
        String line = null;
        int matrixRows = 0;
        int matrixColluns = 0;
        List<Integer> nd = new ArrayList<Integer>();
        List<Integer> np = new ArrayList<Integer>();
        List<String> lista = new ArrayList<String>();
        List<String> lines = new ArrayList<String>();

        try {

            DataInputStream DIi1 = new DataInputStream(f);
            BufferedReader in = new BufferedReader(new InputStreamReader(DIi1));
            line = in.readLine();
            while (line != null) {

                lines.add(clearString(line));

                    StringTokenizer parser = new StringTokenizer(clearString(line));
                    nd.add(parser.countTokens());
                    while (parser.hasMoreTokens()) {
                        String aux = parser.nextToken();
                        if (!lista.contains(aux.toLowerCase()))
                        lista.add(aux.toLowerCase());
                    }
                    
                line = in.readLine();

            }

        } catch (Exception e) {
            e.printStackTrace();
        }


        matrixColluns = lines.size();
        matrixRows = lista.size();
        
        int k;
        for(String sl :lista){
            k=0;
            for(int j=0; j<lines.size();j++){
                if ((' '+(lines.get(j).toLowerCase())+' ').contains(' '+sl+' ')){
                    k++;
                }
            }
            np.add(k);
        }

        double[][] array = new double[matrixRows][matrixColluns];
        int ig=0;
        for (String sl : lista){

            for(int j = 0; j < matrixColluns;j++){
                
                StringTokenizer parser = new StringTokenizer(lines.get(j));

                    while (parser.hasMoreTokens()) {

                      if (sl.equals(parser.nextToken().toLowerCase())){
                          array[ig][j] = array[ig][j]+1;
                      }

                    }       
            }

            ig++;
        }

        //TF-IDF

        for (int i = 0; i < matrixRows; i++){
            for(int j = 0; j < matrixColluns;j++){
                if ((nd.get(j)==0) || (np.get(i)==0)){
                    array[i][j] =0;
                }else{
                    array[i][j] = (array[i][j]/(1.0*nd.get(j)))* Math.log10(matrixColluns * 1.0/np.get(i));
                }
            }
        }

       return new TDMElements(lines,lista, new Matrix(array));
    }

Boa tarde!

Qual é o objetivo final deste código?
Você já identificou quais são os pontos principais da demora?

[quote=Algebra]Olá pessoal, mais uma da série de otimização de código:

Tenho um algoritmo muito grande que com um corpus grande demora 3987 milisegundos. Aceito sugestões para ganhar performance, la vái:
[/quote]

:lol: :lol:

Veja que à segunda vez já é se aproveitar para os outros fazerem o trabalho por si.
Não aprendeu nada com a outra thread ? As técnicas são sempre as mesmas. Revejas o comentários do pessoal que vai conseguir bastantes melhorias.

E por favor implmente uma classe Matrix e não use array de arrays que altamente não performático (porque usa for de for). Esta é a única alteração que não tinha na outra thread e precisa nesta.
Tb não use double. É pedir para ter problemas depois com os calculos.

Bem sergiotaborda não quero fazer ninguem “trabalhar pra mim” este espaço é reservado para todo tipo de discussões a respeito da “programação java”. Obrigado pelo seu comentário proveitoso.

Att

[quote=Algebra]Bem sergiotaborda não quero fazer ninguem “trabalhar pra mim” este espaço é reservado para todo tipo de discussões a respeito da “programação java”. Obrigado pelo seu comentário proveitoso.

Att[/quote]

Ajudaria se vc explicasse o formato do arquivo e os nomes das variáveis tipo, o que é np e nd
e porque estão sendo feitos aqueles fors no final. Seria importante tb explicar o que faz clearString

Uma dica não é na usar String. Converter o line para array de double ou para a mtriz o mais cedo possivel.
Uma classe matriz mais esperta ajuda também. Não user array de array. Implemente uma Matrix com um único array como private ( ou com um HashMap)

quando vc tem for de for vc tem NxK complexidade e isso é sempre ruim. E vc tem os mesmos cliclos umas 4 vezes. Tente fazer tudo em um ciclo só, o tempo diminui logo para 1/4.

O primeiro for pode ser apenas

 line = in.readLine();  

 MatrixRow[] row = split(line);
 Matrix matrix = new Matrix(row.length);
 
matrix.addRow(row);
     line = in.readLine();  

            while (line != null) {  
   MatrixRow[] row = split(line);
matrix.addRow(row);
                line = in.readLine();  
  
            }