Array lenta em applet

4 respostas
J

Olá,

Em um complexo applet eu tenho vários arrays, mas um deles é crítico por causa de seu tamanho.

Ele está declarado assim:

int [][] elem = new int [150000][15]

Tanto a carga de valores, quanto a pesquisa de valores acontecem por instrução FOR.

Quando o applet processa até cerca de 5000x15 elementos no array o tempo de processamento é normal.

Mas quando ele processa com mais de 5000x15 elementos no array o tempo de processamento degrada desproporcionalmente, exemplos:

Processamento com 5000x15 = 1 minuto

Processamento com 20000x15 = 60 minutos

Supondo ser questão de memória limitada, usei -Xmx300m no painel de controle/Java do Windows, mas nada mudou.

Agradeço se alguém puder ajudar.

4 Respostas

E

O tamanho dessa matriz é pelo menos* 4 x 150000 x 15, ou seja, 9MB, então acredito que esse não é o problema (falta de memória). Não seria alguma coisa com seu algoritmo?

  • Na verdade é mais, porque a declaração diz que você tem 150000 objetos int[16] e um objeto int[150000][]. Como cada objeto tem um overhead de pelo menos 16 bytes, na verdade você estaria ocupando mais 2,4MB além dos 9MB estimados, e isso só para esse seu array.

Será que a máquina tem memória suficiente? Pode ser que você veja uma atividade muito grande no seu disco, devido ao fato de estar usando a memória de “swap”, não a memória RAM física.

E

Uma coisa que é um lixo no Java é que arrays bidimensionais no Java não existem. Quando você escreve:

int[][] elem = new int[150000][15];

na verdade você está criando 150000 objetos int[15] e um objeto int[][].

Deveria haver algo como:

int[,] elem = new int[150000,15];

como em uma certa linguagem que não vou citar, para não ofender os brios de ninguém.

Se você acha que a dupla indireção que é feita pela declaração tosca de arrays bidimensionais pode estar deixando seu programa mais lento, experimente calcular você mesmo os índices. Use um array unidimensional:

int[] elem = new int [150000*15];

e a seguir, em vez de acessar um elemento por [i][j], use:

elem [i + j*150000]
ou
elem [i*15 + j]

dependendo de como você tem de organizar seus dados (se à moda Fortran ou à moda C ou Java).

J

enantiomero,

Há memória Java suficiente e não há atividade em disco, li algo sobre heap size, que é uma outra limitação de memória, de empilhamento, mas ainda não li algo consistente a respeito.

Suspeito que possa ser falta de memória contígua, por causa do tamanho do array, então poderia haver muito swap, mas na própria memória.

A sugestão sobre mudar a estrutura da array, tornando-a unidimensional, seria um tanto trabalhosa, pois na verdade são vários programas que usam a mesma array e em vários instantes diferentes, então vou aguardar mais um pouco por outra solução, de qualquer forma eu agradeço sua atenção.

J

Localizei o problema e uma solução para ele, talvez possa ser útil para alguém.

Ao final do applet os dados da array são formatados para serem enviados para o servidor.

E o problema estava aí, a array, em si, era inocente.

A soma de Strings é uma operação normalmente lenta, mas ela degrada muito, quando o string vai aumentando de tamanho e isso eu não sabia.

A solução que usei foi StringBuffer dadostemp = new StringBuffer(); formatando com append e ao final transformar em String, com String dadosfinal = dadostemp.toString(); (solução obtida na internet).

Exemplo:

StringBuffer dadostemp = new StringBuffer();

for (int i = 0; i < 150001; i++)

{

for (int j= 0; j < 16; j++)

{

dadostemp.append(elem[i][j]) ;

}

}

String dadosfinal = dadostemp.toString();

Isso elimina a degradação e é uma formatação mais rápida, independente da degradação.

Agradeço a quem tentou ajudar.

Criado 17 de setembro de 2009
Ultima resposta 20 de set. de 2009
Respostas 4
Participantes 2