como calcular o tempo que cada procedure leva para ser executada

02/06/2020

0

Bom dia, no meu sistema eu tenho uma Unit Funções e nela organizo todas as funções e procedures do sistema.

esse é um exemplo de uma das varias procedures que utilizo para exportar informações das movimentações diárias, no total tenho mais de 80 procedures que alimentam um TXT todos os dias ao exportar o caixa diario, o tempo de execução dessas procedures costuma sofre mudança (durante o dia a movimentação da empresa pode variar e com isso alimentar mais um tabela do que outra) com isso é normal que dessas mais de 80 procedures 8 ou 10 apresentem uma certa lentidão ao montar os dados.

a ideia é utilizar o GetTickCount para avaliar o tempo de execução delas e salvar em um TXT ex: (Exporta_Vendas_Diversas: 0,406).
O chato é fazer isso para cada uma delas.

E pensei em criar duas procedures, uma para iniciar o GetTickCount e outra para finalizar mas assim eu ainda teria de colocar essas duas procedures em cada uma das 80 que alimentam o meu TXT do caixa diário.

procedure Exporta_Vendas_Diversas(lbestado : TLabel);
var inicio, final : Cardinal;
tempo : Extended;
arq: TextFile;
Arquivo, path, nome : String;

begin
// teste *************************
inicio := GetTickCount;
// teste **************************

DtMdlExportaCaixa.FDVendasDiversas.Active := False;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('dataini').Value := gf_data_ini;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('datafim').Value := gf_data_fim;
DtMdlExportaCaixa.FDVendasDiversas.Active := True;

DtMdlExportaCaixa.FDVendasDiversas.first;

while not DtMdlExportaCaixa.FDVendasDiversas.eof do
begin
Cont := 'VDI';
Cont := (cont + Campo_esquerda(formatdatetime('ddmmyyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value),8, ' '));
Cont := (cont + Campo_esquerda(formatfloat('00', DtMdlExportaCaixa.FDVendasDiversasHORA.Value), 2, ' ' ));
Cont := (cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasP_GRUPO.Value, 6, ' '));
Cont := (Cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasI_CODPROD.Value, 14, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasQUANT_TOTAL.Value*100), 10, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasVALOR_TOTAL.Value*100), 10, ' '));
//lista.Add(Cont);
Writeln(FD, Cont);
DtMdlExportaCaixa.FDVendasDiversas.Next;

updatestatus('NFCe '+formatdatetime('dd/mm/yyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value), lbestado);
end;

// teste *****************************************************************************************
final := GetTickCount;
nome:= 'Exporta_Vendas_Diversas';
path := 'C:\Posto';
tempo := (final - inicio) / 1000;
AssignFile(arq, path+'\TempoExec.TXT');
Rewrite(arq);
Writeln(arq, nome+': '+FloatToStr(tempo));

CloseFile(arq);
//***************************************************************************************************
end;
Emanuel Gonçalves

Emanuel Gonçalves

Responder

Post mais votado

02/06/2020

Crie uma rotina que fará o cálculo do tempo e chame-a passando tua rotina como parâmetro. Assim não precisa alterar 80 procedures.
Algo assim:
type
  TProcedure = procedure;

function CalculaExecucao(procedimento: TProcedure): int64;

implementation

function CalculaExecucao(procedimento: TProcedure): int64;
var
  StopWatch: TStopwatch;
  ElapsedMillseconds: Int64;
begin
  StopWatch := TStopwatch.StartNew; // iniciar o contador de tempo
  procedimento; // executa a procedure passada como parâmetro
  Result := StopWatch.ElapsedMilliseconds; // retorna o tempo de execução
end;

daí você altera somente as chamadas às funções:
var
  tempo_gp_dia, tempo_cl_dia: int64;
begin
  tempo_gp_dia := CalculaExecucao(exporta_GP_Dia);
  tempo_cl_dia := CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo de cada varíavel, pois terá o tempo de execução individualizado

se te interessa somente o tempo total:
var
  tempo: int64;
begin
  tempo := 0;
  tempo := tempo + CalculaExecucao(exporta_GP_Dia);
  tempo := tempo + CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo da varíavel tempo

Uma outra sugestão:
Se as procedures chamadas não dependem umas das outras, avalie o uso de Threads, que assim você reduzirá bastante o tempo de processamento.

Emerson Nascimento

Emerson Nascimento
Responder

Mais Posts

02/06/2020

Leandro Carvalho

Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;
Responder

02/06/2020

Emanuel Gonçalves

Desculpa, não compreendi

Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;
Responder

02/06/2020

Leandro Carvalho

Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;


Ainda podemos melhorar:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Origem, Path: String; Inicio, Final: TDateTime);
var
 Arq: TextFile;
begin
 AssignFile(Arq, Path + '\\TempoExec.txt'); 
 Rewrite(Arq); 
 Write(Arq, Origem + ': ' + FormatDateTime('hh:nn:ss.zzz', (Inicio- Final))); 
 CloseFile(Arq); 
end;
Responder

02/06/2020

Emanuel Gonçalves

Veja bem, o trecho de código abaixo está presente em uma das chamada que uso para exportar as informações do caixa. Observe que eu tenho varias procedures (exporta_gp, exporta_cl ......) a ideia é identificar o tempo individual de cada uma delas

try
try
verifica_vazios := True;

if DtMdl.FDInformacoesI_COD_UNID.Value = '99' then
begin
exporta_GP_Dia;
exporta_CL_Dia;
exporta_CB_Dia;
end;

Exporta_PD_Dia;
Exporta_VT_Dia;
Exporta_RP_Dia;
Exporta_EX_Dia;
Exporta_VD_Dia;
Exporta_AJ_Dia;
Exporta_LA_Dia;
Exporta_GN_Dia;
Exporta_OL_Dia;
Exporta_FC_Dia;
Exporta_PL_Dia;
Exporta_CT_Dia;
Exporta_VB_Dia;
Exporta_PR_Dia;

if not(verifica_vazios)then // SE o Exporta_PR falhar
begin
Application.MessageBox(pchar('O Tipo de Combustível do Produto '+tipo_comb+' não foi informado!'), 'AVISO!!!', MB_OK + MB_ICONWARNING);
UpdateStatus( 'Exportação Interrompida.', LbEstado);
Application.ProcessMessages;
exit;
end;

Exporta_PP_Dia;

Exporta_CH_Dia;

Exporta_DS_Dia;
Exporta_LB_Dia;
Exporta_DC_Dia;

if DtMdl.FDInformacoesI_COD_UNID.Value <> '99' then
begin
Exporta_PPGTO_Dia;
Exporta_cartoes_PGTO_Dia();
Exporta_Grupos_Total_Tributacao();
//Exporta_ECF(lbestado); // Provocanto muita lentidão na exportação do caixa
Exporta_Vendas_Diversas(lbestado);
end;

//Lista.SaveToFile(path+arquivo);
except
on E: Exception do
begin
Application.MessageBox(pwidechar('O processamento do arquivo não foi concluido '+'!'+#13+E.message), 'Aviso', MB_OK);
UpdateStatus(#13+'Falha no processamento das informções !',LbEstado);
end;
end;
finally
//Lista.Free;
closefile ( FD );
end;





Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;


Ainda podemos melhorar:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Origem, Path: String; Inicio, Final: TDateTime);
var
 Arq: TextFile;
begin
 AssignFile(Arq, Path + '\\\\TempoExec.txt'); 
 Rewrite(Arq); 
 Write(Arq, Origem + ': ' + FormatDateTime('hh:nn:ss.zzz', (Inicio- Final))); 
 CloseFile(Arq); 
end;
Responder

02/06/2020

Leandro Carvalho

Veja bem, o trecho de código abaixo está presente em uma das chamada que uso para exportar as informações do caixa. Observe que eu tenho varias procedures (exporta_gp, exporta_cl ......) a ideia é identificar o tempo individual de cada uma delas

try
try
verifica_vazios := True;

if DtMdl.FDInformacoesI_COD_UNID.Value = '99' then
begin
exporta_GP_Dia;
exporta_CL_Dia;
exporta_CB_Dia;
end;

Exporta_PD_Dia;
Exporta_VT_Dia;
Exporta_RP_Dia;
Exporta_EX_Dia;
Exporta_VD_Dia;
Exporta_AJ_Dia;
Exporta_LA_Dia;
Exporta_GN_Dia;
Exporta_OL_Dia;
Exporta_FC_Dia;
Exporta_PL_Dia;
Exporta_CT_Dia;
Exporta_VB_Dia;
Exporta_PR_Dia;

if not(verifica_vazios)then // SE o Exporta_PR falhar
begin
Application.MessageBox(pchar('O Tipo de Combustível do Produto '+tipo_comb+' não foi informado!'), 'AVISO!!!', MB_OK + MB_ICONWARNING);
UpdateStatus( 'Exportação Interrompida.', LbEstado);
Application.ProcessMessages;
exit;
end;

Exporta_PP_Dia;

Exporta_CH_Dia;

Exporta_DS_Dia;
Exporta_LB_Dia;
Exporta_DC_Dia;

if DtMdl.FDInformacoesI_COD_UNID.Value <> '99' then
begin
Exporta_PPGTO_Dia;
Exporta_cartoes_PGTO_Dia();
Exporta_Grupos_Total_Tributacao();
//Exporta_ECF(lbestado); // Provocanto muita lentidão na exportação do caixa
Exporta_Vendas_Diversas(lbestado);
end;

//Lista.SaveToFile(path+arquivo);
except
on E: Exception do
begin
Application.MessageBox(pwidechar('O processamento do arquivo não foi concluido '+'!'+#13+E.message), 'Aviso', MB_OK);
UpdateStatus(#13+'Falha no processamento das informções !',LbEstado);
end;
end;
finally
//Lista.Free;
closefile ( FD );
end;





Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;


Ainda podemos melhorar:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Origem, Path: String; Inicio, Final: TDateTime);
var
 Arq: TextFile;
begin
 AssignFile(Arq, Path + '\\TempoExec.txt'); 
 Rewrite(Arq); 
 Write(Arq, Origem + ': ' + FormatDateTime('hh:nn:ss.zzz', (Inicio- Final))); 
 CloseFile(Arq); 
end;


No início da função ou procedimento chame faça:
HoraInicial := Now;

E no final faça:
HoraFinal := Now;
CalculaTempoGasto('Nomedasuafuncaoouprecedimento', 'Ondevaisersalvootxt', HoraInicial, HoraFinal)

Responder

02/06/2020

Emanuel Gonçalves

Compreendi ! Eu apenas estou tentando evitar ter que fazer isso em cada uma delas kkkkk

Veja bem, o trecho de código abaixo está presente em uma das chamada que uso para exportar as informações do caixa. Observe que eu tenho varias procedures (exporta_gp, exporta_cl ......) a ideia é identificar o tempo individual de cada uma delas

try
try
verifica_vazios := True;

if DtMdl.FDInformacoesI_COD_UNID.Value = '99' then
begin
exporta_GP_Dia;
exporta_CL_Dia;
exporta_CB_Dia;
end;

Exporta_PD_Dia;
Exporta_VT_Dia;
Exporta_RP_Dia;
Exporta_EX_Dia;
Exporta_VD_Dia;
Exporta_AJ_Dia;
Exporta_LA_Dia;
Exporta_GN_Dia;
Exporta_OL_Dia;
Exporta_FC_Dia;
Exporta_PL_Dia;
Exporta_CT_Dia;
Exporta_VB_Dia;
Exporta_PR_Dia;

if not(verifica_vazios)then // SE o Exporta_PR falhar
begin
Application.MessageBox(pchar('O Tipo de Combustível do Produto '+tipo_comb+' não foi informado!'), 'AVISO!!!', MB_OK + MB_ICONWARNING);
UpdateStatus( 'Exportação Interrompida.', LbEstado);
Application.ProcessMessages;
exit;
end;

Exporta_PP_Dia;

Exporta_CH_Dia;

Exporta_DS_Dia;
Exporta_LB_Dia;
Exporta_DC_Dia;

if DtMdl.FDInformacoesI_COD_UNID.Value <> '99' then
begin
Exporta_PPGTO_Dia;
Exporta_cartoes_PGTO_Dia();
Exporta_Grupos_Total_Tributacao();
//Exporta_ECF(lbestado); // Provocanto muita lentidão na exportação do caixa
Exporta_Vendas_Diversas(lbestado);
end;

//Lista.SaveToFile(path+arquivo);
except
on E: Exception do
begin
Application.MessageBox(pwidechar('O processamento do arquivo não foi concluido '+'!'+#13+E.message), 'Aviso', MB_OK);
UpdateStatus(#13+'Falha no processamento das informções !',LbEstado);
end;
end;
finally
//Lista.Free;
closefile ( FD );
end;





Uma ideia:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Inicio, Final: TDateTime): String;
begin
 return := FormatDateTime('hh:nn:ss.zzz', (Inicio- Final));
end;


Ainda podemos melhorar:

var
 HoraInicial, HoraFinal: TDateTime;

function CalculaTempoGasto(Origem, Path: String; Inicio, Final: TDateTime);
var
 Arq: TextFile;
begin
 AssignFile(Arq, Path + '\\\\TempoExec.txt'); 
 Rewrite(Arq); 
 Write(Arq, Origem + ': ' + FormatDateTime('hh:nn:ss.zzz', (Inicio- Final))); 
 CloseFile(Arq); 
end;


No início da função ou procedimento chame faça:
HoraInicial := Now;

E no final faça:
HoraFinal := Now;
CalculaTempoGasto('Nomedasuafuncaoouprecedimento', 'Ondevaisersalvootxt', HoraInicial, HoraFinal)

Responder

02/06/2020

Claudio Andrade

Bom dia, no meu sistema eu tenho uma Unit Funções e nela organizo todas as funções e procedures do sistema.

esse é um exemplo de uma das varias procedures que utilizo para exportar informações das movimentações diárias, no total tenho mais de 80 procedures que alimentam um TXT todos os dias ao exportar o caixa diario, o tempo de execução dessas procedures costuma sofre mudança (durante o dia a movimentação da empresa pode variar e com isso alimentar mais um tabela do que outra) com isso é normal que dessas mais de 80 procedures 8 ou 10 apresentem uma certa lentidão ao montar os dados.

a ideia é utilizar o GetTickCount para avaliar o tempo de execução delas e salvar em um TXT ex: (Exporta_Vendas_Diversas: 0,406).
O chato é fazer isso para cada uma delas.

E pensei em criar duas procedures, uma para iniciar o GetTickCount e outra para finalizar mas assim eu ainda teria de colocar essas duas procedures em cada uma das 80 que alimentam o meu TXT do caixa diário.

procedure Exporta_Vendas_Diversas(lbestado : TLabel);
var inicio, final : Cardinal;
tempo : Extended;
arq: TextFile;
Arquivo, path, nome : String;

begin
// teste *************************
inicio := GetTickCount;
// teste **************************

DtMdlExportaCaixa.FDVendasDiversas.Active := False;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('dataini').Value := gf_data_ini;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('datafim').Value := gf_data_fim;
DtMdlExportaCaixa.FDVendasDiversas.Active := True;

DtMdlExportaCaixa.FDVendasDiversas.first;

while not DtMdlExportaCaixa.FDVendasDiversas.eof do
begin
Cont := 'VDI';
Cont := (cont + Campo_esquerda(formatdatetime('ddmmyyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value),8, ' '));
Cont := (cont + Campo_esquerda(formatfloat('00', DtMdlExportaCaixa.FDVendasDiversasHORA.Value), 2, ' ' ));
Cont := (cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasP_GRUPO.Value, 6, ' '));
Cont := (Cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasI_CODPROD.Value, 14, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasQUANT_TOTAL.Value*100), 10, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasVALOR_TOTAL.Value*100), 10, ' '));
//lista.Add(Cont);
Writeln(FD, Cont);
DtMdlExportaCaixa.FDVendasDiversas.Next;

updatestatus('NFCe '+formatdatetime('dd/mm/yyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value), lbestado);
end;

// teste *****************************************************************************************
final := GetTickCount;
nome:= 'Exporta_Vendas_Diversas';
path := 'C:\\Posto';
tempo := (final - inicio) / 1000;
AssignFile(arq, path+'\\TempoExec.TXT');
Rewrite(arq);
Writeln(arq, nome+': '+FloatToStr(tempo));

CloseFile(arq);
//***************************************************************************************************
end;




Procure pela classe TStopwatch no delphi, tem exatamente o que você esta precisando.
Responder

02/06/2020

Leandro Carvalho

Bom dia, no meu sistema eu tenho uma Unit Funções e nela organizo todas as funções e procedures do sistema.

esse é um exemplo de uma das varias procedures que utilizo para exportar informações das movimentações diárias, no total tenho mais de 80 procedures que alimentam um TXT todos os dias ao exportar o caixa diario, o tempo de execução dessas procedures costuma sofre mudança (durante o dia a movimentação da empresa pode variar e com isso alimentar mais um tabela do que outra) com isso é normal que dessas mais de 80 procedures 8 ou 10 apresentem uma certa lentidão ao montar os dados.

a ideia é utilizar o GetTickCount para avaliar o tempo de execução delas e salvar em um TXT ex: (Exporta_Vendas_Diversas: 0,406).
O chato é fazer isso para cada uma delas.

E pensei em criar duas procedures, uma para iniciar o GetTickCount e outra para finalizar mas assim eu ainda teria de colocar essas duas procedures em cada uma das 80 que alimentam o meu TXT do caixa diário.

procedure Exporta_Vendas_Diversas(lbestado : TLabel);
var inicio, final : Cardinal;
tempo : Extended;
arq: TextFile;
Arquivo, path, nome : String;

begin
// teste *************************
inicio := GetTickCount;
// teste **************************

DtMdlExportaCaixa.FDVendasDiversas.Active := False;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('dataini').Value := gf_data_ini;
DtMdlExportaCaixa.FDVendasDiversas.ParamByName('datafim').Value := gf_data_fim;
DtMdlExportaCaixa.FDVendasDiversas.Active := True;

DtMdlExportaCaixa.FDVendasDiversas.first;

while not DtMdlExportaCaixa.FDVendasDiversas.eof do
begin
Cont := 'VDI';
Cont := (cont + Campo_esquerda(formatdatetime('ddmmyyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value),8, ' '));
Cont := (cont + Campo_esquerda(formatfloat('00', DtMdlExportaCaixa.FDVendasDiversasHORA.Value), 2, ' ' ));
Cont := (cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasP_GRUPO.Value, 6, ' '));
Cont := (Cont + Campo_esquerda(DtMdlExportaCaixa.FDVendasDiversasI_CODPROD.Value, 14, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasQUANT_TOTAL.Value*100), 10, ' '));
Cont := (Cont + Campo_direita(FormatFloat('#########0', DtMdlExportaCaixa.FDVendasDiversasVALOR_TOTAL.Value*100), 10, ' '));
//lista.Add(Cont);
Writeln(FD, Cont);
DtMdlExportaCaixa.FDVendasDiversas.Next;

updatestatus('NFCe '+formatdatetime('dd/mm/yyyy', DtMdlExportaCaixa.FDVendasDiversasM_DATA_MOVIM.Value), lbestado);
end;

// teste *****************************************************************************************
final := GetTickCount;
nome:= 'Exporta_Vendas_Diversas';
path := 'C:\\\\Posto';
tempo := (final - inicio) / 1000;
AssignFile(arq, path+'\\\\TempoExec.TXT');
Rewrite(arq);
Writeln(arq, nome+': '+FloatToStr(tempo));

CloseFile(arq);
//***************************************************************************************************
end;




Procure pela classe TStopwatch no delphi, tem exatamente o que você esta precisando.


Boa Cláudio.
Essa eu não sabia.
Mas pelo que li essa classe está disponível a partir do Delphi 10.

Segue o link de como usar a classe Emanuel
https://medium.com/@viniciuss.sanchez/diagnostico-de-performance-usando-tstopwatch-e-ttimespan-ed13c21311af
Responder

02/06/2020

Emanuel Gonçalves

Eu encontrei também !!

http://edgarpavao.com/2017/08/07/diagnostico-de-performance-com-tstopwatch-e-ttimespan/
Responder

02/06/2020

Emanuel Gonçalves

perfeito, o detalhe é que o meu delphi é o XE6


Crie uma rotina que fará o cálculo do tempo e chame-a passando tua rotina como parâmetro. Assim não precisa alterar 80 procedures.
Algo assim:
type
  TProcedure = procedure;

function CalculaExecucao(procedimento: TProcedure): int64;

implementation

function CalculaExecucao(procedimento: TProcedure): int64;
var
  StopWatch: TStopwatch;
  ElapsedMillseconds: Int64;
begin
  StopWatch := TStopwatch.StartNew; // iniciar o contador de tempo
  procedimento; // executa a procedure passada como parâmetro
  Result := StopWatch.ElapsedMilliseconds; // retorna o tempo de execução
end;

daí você altera somente as chamadas às funções:
var
  tempo_gp_dia, tempo_cl_dia: int64;
begin
  tempo_gp_dia := CalculaExecucao(exporta_GP_Dia);
  tempo_cl_dia := CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo de cada varíavel, pois terá o tempo de execução individualizado

se te interessa somente o tempo total:
var
  tempo: int64;
begin
  tempo := 0;
  tempo := tempo + CalculaExecucao(exporta_GP_Dia);
  tempo := tempo + CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo da varíavel tempo

Uma outra sugestão:
Se as procedures chamadas não dependem umas das outras, avalie o uso de Threads, que assim você reduzirá bastante o tempo de processamento.
Responder

02/06/2020

Emanuel Gonçalves

adaptei a sugestão do Emerson

function CalculaExecucao(procedimento: TProcedure; nomeprocedure : String): int64;
var HoraInicial, HoraFinal: TDateTime;
path : String;
arq: TextFile;
begin
HoraInicial := Now;
procedimento;
HoraFinal := Now;

path := 'C:\\Posto';
AssignFile(Arq, Path + '\\\\TempoExec.txt');
Rewrite(Arq);
Writeln(Arq, nomeprocedure + ': ' + FormatDateTime('hh:nn:ss:mm', (HoraInicial - HoraFinal)));
CloseFile(Arq);
end;

Crie uma rotina que fará o cálculo do tempo e chame-a passando tua rotina como parâmetro. Assim não precisa alterar 80 procedures.
Algo assim:
type
  TProcedure = procedure;

function CalculaExecucao(procedimento: TProcedure): int64;

implementation

function CalculaExecucao(procedimento: TProcedure): int64;
var
  StopWatch: TStopwatch;
  ElapsedMillseconds: Int64;
begin
  StopWatch := TStopwatch.StartNew; // iniciar o contador de tempo
  procedimento; // executa a procedure passada como parâmetro
  Result := StopWatch.ElapsedMilliseconds; // retorna o tempo de execução
end;

daí você altera somente as chamadas às funções:
var
  tempo_gp_dia, tempo_cl_dia: int64;
begin
  tempo_gp_dia := CalculaExecucao(exporta_GP_Dia);
  tempo_cl_dia := CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo de cada varíavel, pois terá o tempo de execução individualizado

se te interessa somente o tempo total:
var
  tempo: int64;
begin
  tempo := 0;
  tempo := tempo + CalculaExecucao(exporta_GP_Dia);
  tempo := tempo + CalculaExecucao(exporta_CL_Dia);
  // e assim por diante
  // depois você apresenta ou grava o conteúdo da varíavel tempo

Uma outra sugestão:
Se as procedures chamadas não dependem umas das outras, avalie o uso de Threads, que assim você reduzirá bastante o tempo de processamento.
Responder

02/06/2020

Emanuel Gonçalves

O detalhe é que dessa maneira grava apenas o tempo da ultima procedure executada

function CalculaExecucao(procedimento: TProcedure; nomeprocedure : String): int64;
var HoraInicial, HoraFinal: TDateTime;
path : String;
arq: TextFile;
begin
HoraInicial := Now;
procedimento;
HoraFinal := Now;

path := 'C:\\\\Posto';
AssignFile(Arq, Path + '\\\\\\\\TempoExec.txt');
Rewrite(Arq);
Writeln(Arq, nomeprocedure + ': ' + FormatDateTime('hh:nn:ss:mm', (HoraInicial - HoraFinal)));
CloseFile(Arq);
end;
Responder

02/06/2020

Emerson Nascimento

Acredito que a classe TStopwatch esteja disponível na tua versão do Delphi.
Para usá-la é necessário acrescentar a System.Diagnostics na cláusula uses do teu fonte.

No caso do arquivo gravar somente a última execução, o problema está no uso de Rewrite(). Esta função limpa o arquivo.
Troque Rewrite() por Append().

Fica assim:
function CalculaExecucao(procedimento: TProcedure; nomeprocedure : String): int64;
var HoraInicial, HoraFinal: TDateTime;
  path : String;
  arq: TextFile;
begin
  HoraInicial := Now;
  procedimento;
  HoraFinal := Now;

  path := 'C:\\\\\\\\Posto';
  AssignFile(Arq, Path + '\\\\\\\\\\\\\\\\TempoExec.txt');
  Append(Arq); // Rewrite(Arq);
  Writeln(Arq, nomeprocedure + ': ' + FormatDateTime('hh:nn:ss:mm', (HoraInicial - HoraFinal)));
  CloseFile(Arq);
end;


E mantenho a minha sugestão sobre o uso de Threads.
Responder

04/06/2020

Emanuel Gonçalves

Boa tarde senhores

preciso de mais uma dica

verificar o tempo na exportação dos dados nós resolvemos !

agora preciso de uma dica para calcular o tempo na importação do dados

veja bem , no processo de importação eu tenho varias function´s recebendo os mesmos parâmetros

ex:
function import_dc_diaria (Var FDL : TextFile; SP : TFDStoredProc; str_lida, Unidade, Periodo : string; importa : boolean) : String ;
var elimina_reg : string;
begin
elimina_reg := 'S';
SP.StoredProcName := 'INSERT_DESCONTOS_FIXOS';
SP.Prepare;

Try
while copy ( str_lida, 1, 2) = 'DC' do
begin
SP.ParamByName('elimina').Value := elimina_reg;
SP.ParamByName('dataini').Value := copy (Periodo,1,10);
SP.ParamByName('datafim').Value := copy (Periodo,14,10);
SP.ParamByName('UNIDADE').Value := copy (Unidade,1,2);
SP.ParamByName('DATADIA').Value := strtodate((copy (str_lida,9,2))+'/'+(copy (str_lida,7,2))+'/'+(copy (str_lida,3,4)));
SP.ParamByName('CODPROD').Value := copy (str_lida,11,6);
SP.ParamByName('DESCFIXO').Value := StrToFloat (copy (str_lida,17,6)) / 100;
SP.ParamByName('QUANT').Value := StrToFloat (copy (str_lida,23,8)) /10;
SP.ParamByName('BRUTO').Value := StrToFloatdef (copy (str_lida,31,9),0) /100;
SP.ParamByName('LUCRO').Value := StrToFloatdef (copy (str_lida,40,9),0) /100;
SP.ExecProc;
str_lida := ler_linha(FDL);
elimina_reg := 'N';
end;
except
on E:Exception do
begin
Application.MessageBox(Pchar('Problemas na Importação de INSERT_ABASTECIMENTO.'
+#13+str_lida+#13+E.message), 'Aviso !', MB_OK);
DtMdl.FB_DataBase.RollbackRetaining;
Raise;
end;
end;
dtmdl.FB_DataBase.CommitRetaining;
result := str_lida;
end;

A ideia seria utilizar a procedure que calcula o tempo na exportação agora na importação (pode ser uma function)

procedure CalculaExecucao(procedimento: TProcedure; nomeprocedure : String);
var tempoini, tempofim : TDateTime;
arq_tempo : TextFile;
valor, horas, minutos, segundos : Integer;
resultado : String;
begin
tempoini := now();
procedimento();
tempofim := now();

valor := (SecondsBetween(tempoini, tempofim));
horas := valor div 3600;
minutos := valor div 60 - horas * 60;
segundos := (valor - (horas *3600 + minutos * 60))+1;
Resultado := Format('%0.2d:%0.2d:%0.2d', [horas, minutos, segundos]);

AssignFile(arq_tempo, gsAppPath+'TempoExec.txt');
Append(arq_tempo);
Writeln(arq_tempo, nomeprocedure + ': ' + resultado);
CloseFile(arq_tempo);
end;

No sistema as funções são chamadas assim

str_Diario := import_dc_diaria (FD_Diario, SPGenerica, str_Diario, LblUnidade.Caption, LblPeriodo.Caption, true);
Responder

04/06/2020

Emerson Nascimento

tente isto:
type
  TProcedure = procedure; // funciona para qualquer procedure sem parametros
  TFunc1 = function(str: string): string; // funciona para qualquer funcao que receba uma string e retorne uma string

  // você terá de criar um tipo para cada função, com base em seus respectivos parametros e retorno.
  // a função abaixo reflete aquela que você publicou e vai funcionar para todas as funcoes que recebam a mesma
  // lista de parametros (considerando o tipo do parâmetro, não o nome) e tenham o mesmo tipo de retorno.
  TFunImport_dc_diaria = function(var FDL: TextFile; SP: TFDStoredProc; str_lida, Unidade, Periodo: string; importa: boolean): string;

procedure CalculaExecucao(procedimento: TProcedure; nomeprocedure: string); overload;
function CalculaExecucao(funcao: TFunc1; nomefuncao: string; Param1: string): string; overload;
function CalculaExecucao(funcao: TFunImport_dc_diaria; nomefuncao: string;
  var FDL: TextFile; SP: TFDStoredProc; str_lida, Unidade, Periodo: string; importa: boolean): string; overload;
procedure GravaTempo(nomerotina: string; tempoini, tempofim: TDateTime);

implementation

// procedure que calcula o tempo de execucao de qualquer procedure que não tenha parâmetros
procedure CalculaExecucao(procedimento: TProcedure; nomeprocedure: string);
var
  tempoini, tempofim: TDateTime;
begin
  tempoini := now();
  procedimento;
  tempofim := now();

  GravaTempo(nomeprocedure, tempoini, tempofim);
end;

// funcao calcula o tempo de execucao de qualquer funcao que receba um parâmetro string e retorne uma string
function CalculaExecucao(funcao: TFunc1; nomefuncao: string; Param1: string): string; overload;
var
  tempoini, tempofim: TDateTime;
  resultado: string;
 begin
  tempoini := now();
  resultado := funcao(Param1);
  tempofim := now();

  GravaTempo(nomefuncao, tempoini, tempofim);

  result := resultado;
end;

// funcao que calcula o tempo de execução de qualquer função com as seguintes características:
// - Parâmetros: TextFile, TFDStoredProc, string, string, string, boolean
// - Result: string
function CalculaExecucao(funcao: TFunImport_dc_diaria; nomefuncao: string;
  var FDL: TextFile; SP: TFDStoredProc; str_lida, Unidade, Periodo: string; importa: boolean): string; overload;
var
  tempoini, tempofim: TDateTime;
  resultado: string;
begin
  tempoini := now();
  resultado := funcao(FDL, SP, str_lida, Unidade, Periodo, importa);
  tempofim := now();

  GravaTempo(nomefuncao, tempoini, tempofim);

  result := resultado;
end;

// grava no arquivo TempoExec.txt o intervao de tempo entre tempoini e tempofim.
// separei numa função específica porque todas as versões de CalculaExecucao() precisam deste trecho.
procedure GravaTempo(nomerotina: string; tempoini, tempofim: TDateTime);
var
  valor, horas, minutos, segundos: Integer;
  resultado: string;
  arq_tempo: TextFile;
begin
  valor := (SecondsBetween(tempoini, tempofim));
  horas := valor div 3600;
  minutos := valor div 60 - horas * 60;
  segundos := (valor - (horas *3600 + minutos * 60))+1;
  Resultado := Format('%0.2d:%0.2d:%0.2d', [horas, minutos, segundos]);

  AssignFile(arq_tempo, gsAppPath+'TempoExec.txt');
  Append(arq_tempo);
  Writeln(arq_tempo, nomerotina + ': ' + resultado);
  CloseFile(arq_tempo);
end;

para executar:
begin
  CalculaExecucao(exporta_GP_Dia, 'exporta_GP_Dia');
  str_Diario := CalculaExecucao(import_dc_diaria, 'import_dc_diaria', FD_Diario, SPGenerica, str_Diario, LblUnidade.Caption, LblPeriodo.Caption, true);
end;


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar