Array
(
)

alguem consegue um algoritmo mais rapido ?

Fabiano Góes
   - 04 abr 2006

#Código



strSql:=´SELECT COMPE_DES, BANCO_DES, AGENCIA_DES,CONTA_DES, NUMERO_DOC, ´;
strSql := strSql + ´VALOR, SEQ_REG, FLAG ´;
strSql := strSql + ´FROM ´+sTabelaEntrada;

Application.ProcessMessages;

with qryExecutaSQL do
begin
close;
sql.clear;
sql.add(strSql);
open;
First;
end;

Temp := TStringList.Create;
Temp.LoadFromFile(Parametros.Path_Sistema+ ´CAS.TXT´);
lblCont_Mensagem.Visible := True;
cont := 0 ;

for i := 0 to Temp.Count - 1 do
begin
if ( copy( Temp.Strings[i], 01, 01) = ´N´ ) then
if ( copy( Temp.Strings[i], 14, 02) <> ´07´) and
( copy( Temp.Strings[i], 20, 04) <> ´0041´) then
if ( copy( Temp.Strings[i], 51, 02) <> ´36´) and
( copy( Temp.Strings[i], 51, 02) <> ´01´) then
begin
qryUpdateSql(
´UPDATE ´ + sTabelaEntrada + ´ SET FLAG = ´ +#39´*´+39+
´ WHERE COMPE_DES = ´+39+copy(Temp.Strings[i],67,03)+39+
´ AND BANCO_DES = ´+39+copy( Temp.Strings[i], 83, 03) +39+
´ AND AGENCIA_DES = ´+39+copy( Temp.Strings[i], 86, 04) +39+
´ AND CONTA_DES LIKE ´+39+´¬´+copy(Temp.Strings[i],98,10) + ´¬´ +39+
´ AND NUMERO_DOC = ´+39+copy(Temp.Strings[i],70,06)+39+
´ AND VALOR LIKE ´+39+´¬´+copy(Temp.Strings[i],30,16)+´¬´+39+´ ´);

cont := cont + 1;
lblCont.Caption := IntToStr( cont );
Application.ProcessMessages;
end; // if
end; // for


este algoritimo até está funcionando bem com arquivos pequenos até 5.000 registros mais quando passa disso ai eu acho que fica meio demorado.
#Código

obs: o sistema chega a processar arquivos de mais de 50.000 registros

Não sei se estou fazendo da melhor maneira.
Se alguem puder me ajudar eu agradeço !!!


Marioguedes
   - 04 abr 2006

Talvez meu raciocínio não tenha muito efeito, porém creio que o fato de você carregar o TXT em uma StringList esteja prejudicando o desempenho porque no caso vai tudo para memória.

Sugiro então que você leia o TXT com as rotinas ReadLn e assim talvez ter um desempenho mais adequado.


Rcasistemas
|
MVP
    04 abr 2006

Tente usar BeginUpdate e EndUpdate... (metodos do stringlist), coloque no inicio do seu codigo o BeginUpdate, e no final EndUpdate...

Faz o teste ae..

Abraços


Fabiano Góes
   - 04 abr 2006

_anderson_

Ler texto com Stringlist é mais lento que ler com ReadLn ?????

porque ?

-----------------------------------------------------------

marioguedes

qual a logica de usar ´BeginUpdate e EndUpdate´

não entendi porque isso deixaria o processamento mais rapido


Rjun
   - 04 abr 2006

O que você considera como demorado?


Fabiano Góes
   - 05 abr 2006

Rjun,

Em um processamento de 7.000 registros leva ´00:04:30 hs´
Quatro minutos e meio

levando em consideração que o sistema deve processar arquivos de até
80.000 registros

acho que está demorado !!!!


Rjun
   - 05 abr 2006

O que é esse qryUpdateSql?


Massuda
   - 05 abr 2006

No seu caso, seus arquivos texto parecem ser grandes. Use AssignFile/Reset/ReadLn/CloseFile para ler esses arquivos ao invés do TStringList. O TStringList vai tentar carregar todo o arquivo em memória... se cada linha tiver 80 caracteres, um arquivo com 80.000 registros consome 6-7MB de memória e alocar muita de memória em uma única operação demanda um tempo considerável.

Outra coisa que deve ajudar é evitar usar a procedure Copy. Como uma string é um array of Char, seu código pode ser reescrito assim...#Código

var
S: string;
...
S := Temp.Strings[i]; // ou o que for lido com ReadLn
...
if ( S[1] = ´N´ ) then
if not (( S[14] = ´0´ ) and ( S[15] = ´7´ )) and
...
...isso é mais rápido pois o Copy irá criar uma nova string a cada execução e dessa forma não precisa criar nova string.


Paullsoftware
   - 05 abr 2006


Citação:

Ler texto com Stringlist é mais lento que ler com ReadLn ?????

porque ?


sim é mais lento!

Citação:


porque ?


quando vc cria um StringList e você carregada o conteúdo de um txt para ela vc já ocupa dois espaços na memória, o do txt e da StringList levando em conta que o tamanho da StringList vai de acordo com a memória virtual disponível no micro...
fiz um teste aqui em um txt com 20.000 registros e obtive os resultados

Citação:

Nesse teste foi feito apenas a inclusão
Usando StringList = 00:13:38
Usando Copy = 00:08:17
uma diferença bastante considerada, mais não exatamente a StringList que torna o processo mais lento, quando vc importa os dados se for para atualizar deve-se trtá-los antes de iniciar uma transação, fiz um outro teste...

Citação:
Nesse teste foi Feito Inclusão e Alteração sem tratar os dados antes
StringList = 00:18:19
Copy = 00:11:49

depois fiz um teste tratando os dados antes de iniciar a transação, nesse caso somente inicio uma transação se houver alterações...

Citação:
Tratando os dados antes de iniciar uma transação
StringList = 00:14:57
Copy = 00:09:11


sendo assim:

Eu uso StringList mais, somente quando os dados a serem importados são poucos, ou seja, não passam dos 10.000 registros

Detalhe Configuração do Micro[list:a74211ab20]
Cyrix 300
128Mb
Hd 4.3GB
Windows 98[/list:u:a74211ab20] :wink:


Andremuller
   - 05 abr 2006

além do que os colegas disseram (não usar stringlist e copy) não monte toda vez toda SQL, coloque ela somente uma vez e passe os parâmetros por ParamByName


Andremuller
   - 05 abr 2006

se for banco de dados, faz melhor, coloca aquele update dentro de uma stored procedure


Fabiano Góes
   - 06 abr 2006


Citação:
O que é esse qryUpdateSql?


Rjun, qryUpdateSql é uma procedureque recebe uma instrução SQL neste caso como uso ela apenas para Update coloquei este nome
#Código


procedure qryUpdateSql( strSql : String );
begin
with qry do
begin
close;
sql.clear;
sql.add( strSql );
execSql;
end;
end;



Fabiano Góes
   - 10 abr 2006

como criar uma Stored Procedure em FireBird deste Update ?

#Código


var strSql : String;

strSql := ´UPDATE ´ + sTabelaEntrada + ´ SET FLAG = ´ +#39´*´+39+
´ WHERE COMPE_DES = ´+39+copy(Temp.Strings[i],67,03)+39+
´ AND BANCO_DES = ´+39+copy( Temp.Strings[i], 83, 03) +39+
´ AND AGENCIA_DES = ´+39+copy( Temp.Strings[i], 86, 04) +39+
´ AND CONTA_DES LIKE ´+39+´¬´+copy(Temp.Strings[i],98,10) + ´¬´ +39+
´ AND NUMERO_DOC = ´+39+copy(Temp.Strings[i],70,06)+39+
´ AND VALOR LIKE ´+39+´¬´+copy(Temp.Strings[i],30,16)+´¬´+39+´ ´;

with qryUpdate do
begin
close;
sql.clear;
sql.add( strSql );
sql.execSql;
end;