Qual o problema nesse codigo???  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

Pessoal, estou fazendo um programinha que recebe um arquivo .txt com palavras em ingles e filtro ele deixando tudo minusculo, sem acento, cedinha, hifen, virgula, etc.. ou seja, somente o texto de a-z + espaço...
meu codigo que fiz eh esse da filtragem..


Qual o programa...
testei alguns .txt.

* Para um texto com 200 linhas o tempo pra ele fazer isso e jogar num JTextArea foi de 207 milisegundos
* para um texto com 1000 linhas o tempo para ele fazer isso e jogar num JTextArea foi de 7657 milisegundos = 7,6 segundos aproximadamente.
* para um texto com 2000 linhas o tempo para ele fazer isso e jogar num JTextArea foi de 55130 milisegundos = 55 segundos

* o problema vem agora, o texto original tem 5319 linhas, coloquei pra rodar, ja se passou 10 minutos e nao retornou resposta(tb nao deu erro, continua la rodando com processador a 100% mas tive que parar a execução forçadamente pq nao sei quando iria terminar mas esperei 10 minutos e nada)...

eu queria saber o pq dessa demora e se tem como agilizar esses calculos...


ps.: minha primeira implementação foi usando buff.readLine(); e usando substring(i,i+1) para pegar caractere por caractere mas o problema ficava na mudanca de linha que ele considerava como espaco, entre outros problemas na contagem de letras que ja esqueci.. porem no texto completo de 5319 linhas ele demorava em torno de 1 minuto e retornava o texto...

ja usando a ideia de codigo ascii da letra com o metodo read() ele faz a contagem perfeita mas to nesse impasse ai dessa demora(que em tese nao devia demorar tanto ja que pelo metodo substring ele tb verifica caractere por caractere o que no meu teexto original tem em torno de 150.000 caracteres)..

Alguma soluçao pessoal??? e agradeço...

This message was edited 1 time. Last update was at 24/04/2009 15:17:36

gujuser
JavaBaby

Membro desde: 26/03/2009 09:20:40
Mensagens: 75
Offline

Boa tarde,

Nossa cara, tem muito IF isso ae.
Faz com expressão regular, vai economizar tempo, ficar um código limpo, e rápido.

flw.

[]'s
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

opa. vlw pela resposta.

eh que sou novo e nao sei usar expressao regular e meu tempo nao ta muito grande pra estudar isso pois a entrega disso ja esta proxima...

nao creio ser problema dos IFs pois como disse, quando usei com substring, ele demorava em torno de 1 minuto pra retornar o texto completo... com essa nova forma usando read(); ele me da as respostas mais corretas mas esta demorando absurdamente maior que antes o q nao devia ocorrer ja que antes e agora continuo verificando caractere por caractere e no mesmo texto...

Quero tentar resolver dessa forma pois a entrega ja eh proxima, mas de toda forma se alguem puder da dica, alem de corrgiir esse codigo, fazer tb com ER pois eu tenho interesse de otimiza-lo mais na frente...

agradeço a todos.
pmlm
GUJ Master

Membro desde: 20/04/2009 12:20:07
Mensagens: 1198
Localização: Portugal
Online

Não uses Strings que vai sendo incrementadas dentro de ciclos. Para isso usa StringBuilder.
cdorner
JavaBaby
[Avatar]

Membro desde: 15/08/2008 14:49:50
Mensagens: 81
Offline

pmlm wrote:Não uses Strings que vai sendo incrementadas dentro de ciclos. Para isso usa StringBuilder.



RaphaelSantos ele quer dizer pra vc ler sobre String Imutaveis, existem metodos da propria classe String que resolvem os seus problema, tem o toLowerCase(), replaceAll, enfim muitos outros meios de se conseguir oq vc quer fazer, da uma pesquisada melhor ai.

abraço
[Email] [MSN]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

O seu principal problema é usar "+=". Isso é um verdadeiro veneno; use um StringBuilder (Java 5.0 ou posterior) ou StringBuffer.
Outro problema é ler o arquivo caracter por caracter. O correto é ler uma linha de cada vez, já que você está usando BufferedReader.

No seu caso em particular, você pode usar uma expressão regular. Pelo que estou vendo, você quer deixar só as letras e espaços, e se achar um "-" ou "'" você quer trocar por " ", e além disso você quer tornar todas as letras minúsculas. Ou seja, você pode separar sua rotina em 2:


e deixar a parte de leitura separada dessa rotina.
[WWW]
Giulliano
GUJ Master
[Avatar]

Membro desde: 14/11/2006 19:29:38
Mensagens: 1627
Localização: São Paulo
Offline

Eu acho q vc poderia carregar esse arquivo num BufferedReader mesmo...do mesmo modo q vc fez.

Mas na hora de substituir utilize a API da String:



valews

Oracle Certified Master, Java EE 5 Enterprise Architect
Oracle Certified Professional Java Programmer
GiuLLianO MoRRoNi




<UnTouChAbLe>
[Email] [WWW] [MSN]
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

vlw pessoal(thingol tb pelo codigo)...

vejam meu problema...eu nao preciso APENAS retornar o texto sem caracteres estranhos.. ou seja retorna apenas a-z e espaco.. se tiver cedilha, espaco, colchetes, virgula etc ele retira...

qual o problema disso? eh que depois de filtrado o texto, eu preciso calcular a probabilidade de cada palavra... exemplo...se o total de caracteres eh 3000 e a quantidade de letras a eh 1000, a probabilidade de ter a eh de 1000/3000 = 1/3... por isso dentro de cada if tem um somatorio de um vetor...
ou seja, usando expressao regular, cedo ou tarde terei q ler caractere a caractere para achar a qauntidade de cada letra...

estou modificando para StringBuilder para ver se da um resultado bom...

se algeum tiver + alguma sugestao, pq com essa demora o meu professor nao vai querer esperar pra ver
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

Pessoa, so tenho a gradecer a voces..
com o StringBuilder mesmo o texto de 5319 linhas demorou APENAS 19 milisegundos.. incrivel...

so uma pergunta... pq o gargalo foi tao grande ao usar += na String???
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

thingol wrote:O seu principal problema é usar "+=". Isso é um verdadeiro veneno; use um StringBuilder (Java 5.0 ou posterior) ou StringBuffer.
Outro problema é ler o arquivo caracter por caracter. O correto é ler uma linha de cada vez, já que você está usando BufferedReader.

No seu caso em particular, você pode usar uma expressão regular. Pelo que estou vendo, você quer deixar só as letras e espaços, e se achar um "-" ou "'" você quer trocar por " ", e além disso você quer tornar todas as letras minúsculas. Ou seja, você pode separar sua rotina em 2:


e deixar a parte de leitura separada dessa rotina.

thingol, acho que esse seu codigo ai vai ficar beleza, comecei a entender sua logica...irei fazer o teste com ele... muito obrigado.
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

RaphaelSantos wrote:Pessoa, so tenho a gradecer a voces..
com o StringBuilder mesmo o texto de 5319 linhas demorou APENAS 19 milisegundos.. incrivel...

so uma pergunta... pq o gargalo foi tao grande ao usar += na String???


A instrução:

é traduzida para:

e concat é um método de java.lang.String que faz basicamente o seguinte:

Ou seja, você cria 4 objetos e tem 2 cópias para char[]. Se as strings forem um pouco grandes (como linhas de um arquivo texto),
o tempo gasto em alocação e cópias vai ser bem alto.

Se você usar uma StringBuilder todo o tempo, cada "append" não cria novos objetos à toa (só quando
um buffer interno estourar, mas isso não deve ocorrer muito frequentemente, e mesmo assim você pode ter uma
idéia do tamanho aproximado - existe um construtor de StringBuilder que permite passar uma estimativa
do tamanho final da StringBuilder.


[WWW]
Tchello
GUJ Master
[Avatar]

Membro desde: 07/06/2008 14:41:04
Mensagens: 1693
Online

RaphaelSantos wrote:Pessoa, so tenho a gradecer a voces..
com o StringBuilder mesmo o texto de 5319 linhas demorou APENAS 19 milisegundos.. incrivel...

so uma pergunta... pq o gargalo foi tao grande ao usar += na String???


Isso é por que uma String é imutável, ou seja, toda vez que você concatena duas strings na verdade você cria uma terceira, exigindo mais recursos de máquina (processamento e memória).
O que não acontece com a StringBuilder nem com a StringBuffer, pois essas sim são mutáveis e não ficam realocando recursos.
Agora imagine isso pra cada letra de um arquivo de texto de mais de 5 mil linhas... qual lhe parece mais performático?
Com a StringBuilder ele não precisa ficar recriando objetos strings, o que diminui bastante esse gargalo.

ps: A título de informação a diferença entra StringBuilder e StringBuffer é que a segunda é Thread Safe, ou seja, tem os métodos sincronizados pra que apenas uma thread por vez possa acessa-la. Isso a torna mais "lenta" mas em alguns casos é necessário assim como em outros não.

Abraços!

edit: correção ortográfica.

This message was edited 1 time. Last update was at 24/04/2009 16:11:02

Tchello
GUJ Master
[Avatar]

Membro desde: 07/06/2008 14:41:04
Mensagens: 1693
Online

Ok, parece que o thingol e eu respondemos ao mesmo tempo... a explicação dele está melhor.

Enjoy!
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

compreendi o problema do += finalmente..

valeu meus amigos...
RaphaelSantos
JavaGuru

Membro desde: 05/11/2006 02:51:13
Mensagens: 201
Offline

Só mais uma duvida pessoal, se essa concatencao fosse com inteiros ou doubles teria o mesmo problema que teve com String???

caso sim, qual seria a alternativa para inteiro e doubles??
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team