Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Medir tiempo de ejecución usando Timer (Problemas) (https://www.clubdelphi.com/foros/showthread.php?t=33203)

Bauhaus1975 29-06-2006 17:47:59

Medir tiempo de ejecución usando Timer (Problemas)
 
Hola a todos, les comento mi nuevo problema
(Trabajo con Windows2000 y Delphi6)
Tengo en un procedimiento un proceso que tarda mucho en ejecutarse y necesito medir el tiempo de ejecución de dicho proceso. Para ello he añadido un TTimer y un par de procedimientos 'set' y 'end'. El primero se encarga de activar el Timer (Timer.Enabled=true) lo llamo justo antes de la llamada al proceso principal y el segundo justo cuando termina y se encarga de desactivar el Timer.

He puesto unos label en el formulario de tal forma que cada segundo el evento del 'Timer' del timer me pinta el reloj, que avanza segundo a segundo.
Todo esto funciona OK, el problema es cuando se llama al proceso principal que se apodera de la ejecución y el contador ¡no funciona!

También he probado a iniciar el cronómetro por un botón y luego invocar al procedimiento, en cuanto que empieza el éste, el crono deja de funcionar.

¿Alguien sabe como hacer para que ambos procesos puedan funcionar y el contador me cuente el tiempo de cómputo del proceso principal?

Adjunto un esquema de los procedimientos


Código Delphi [-]

procedure Tform1.inicio();
begin
        // Inicialización del cronómetro
        form1.set();
        // Llamada al proceso principal
        resultado := generarProceso([...]);
        // Paramos el cronómetro
        form1.end();
end;

procedure Tform1.set();
begin
        segundos:=0;minutos:=0;horas:=0;dias:=0;
        form1.Timer1.Interval := 1000;
        form1.Timer1.Enabled := true;
end;
 
procedure Tform1.end();
begin
        form1.Timer1.Enabled := false;
end;
 
procedure Tform1.Timer1Timer(Sender: TObject);
begin
segundos := segundos + 1;
if (segundos > 59) then
 begin
 segundos := 0;
 minutos := minutos + 1;
 if (minutos > 59) then
  begin
  minutos := 0;
  horas := horas + 1;
  if (horas > 23) then
   begin
   horas := 0;
   dias := dias + 1;
  end;
 end;
end;
// Pintar el reloj en el form
form1.lbSegundos.Caption := inttostr(segundos);
form1.lbMinutos.Caption := inttostr(minutos);
form1.lbHoras.Caption := inttostr(horas);
form1.lbDias.Caption := inttostr(dias);
end;

Muchas gracias y un saludo.

Sotrono 29-06-2006 18:51:30

Hola, primero te recomiendo que utilices otro método para medir el tiempo, ya que el TTimer es muy impreciso y con tiempos tan largos peor todavia.. :mad:
En Torry podés encontrar varios Timer más precisos.
Otra opción es utilizar la API GetTickCount, documentada acá. Esta función te devuelve la cantidad de tiempo (en milisegundos) que hace que la computadora esta encendida.
Cuando iniciás el proceso guardas el valor que te devuelve GetTickCount y con un TTimer común (con un intervalo menor a 1 segundo) vas comparando el valor que te da GetTickCount con el de la variable y luego haces los cálculos y actualizás los labels.

Cita:

Empezado por Bauhaus1975
el problema es cuando se llama al proceso principal que se apodera de la ejecución y el contador ¡no funciona!

Para solucionar esto tenés que "encerrar" el proceso en un TThread. En la ayuda de Delphi está bien documentada la clase y el buscador de los foros tambien te va a ser de gran ayuda.
EDITO: En lugar de usar un Thread, proba añadiendo Application.ProcessMessages en el proceso.

Bytes!!

Bauhaus1975 29-06-2006 20:28:40

Hola y gracias por tu respuesta.

Perdona, pero tengo poca experiencia con Delphi.
¿Podrías ponerme aunque sea a modo de esquema cómo puedo usar la función GetTickCount como comentas?

Voy a documentarme sobre el TThread, ¿tendría que meter en una hebra ambos procesos?

un saludo.

Sotrono 29-06-2006 22:37:10

Declará a Inicio y T_Actual como Extended;
El codigo que iría antes de iniciar el proceso seria éste:
Código Delphi [-]
  Inicio:= GetTickCount; //En Inicio guardas el valor que te devuelve GetTickCount cuando inicias el proceso
  Timer1.Interval := 300;
  Timer1.Enabled := true;
  //Acá tendrias que inciar el proceso

Y éste es el evento OnTimer del Timer:
Código Delphi [-]
procedure TForm1.Timer1Timer(Sender: TObject);
var dif: extended;
begin
  T_Actual := GetTickCount;
  dif := (T_Actual - Inicio) / 1000; //En dif se almacena cuantos segundos pasaron desde que se inició el proceso
  Label1.Caption := FloatToStr(Round(dif)); //Se redondea dif y se muestra
end;

Cita:

Empezado por Bauhaus1975
Voy a documentarme sobre el TThread, ¿tendría que meter en una hebra ambos procesos?

No sé que tipo de proceso es el que estás ejecutando pero primero proba añadiendo Application.ProcessMessages.
Y si lo haces con Threads, tenés que poner en uno solo el proceso que vos manejas, ya que el TTimer crea un Thread propio.

Lepe 30-06-2006 11:30:26

Con GetTickCount no necesitas un Timer. Aquí tienes un ejemplo sacado de Ians Marteens "midiendo el tiempo con precisión", adaptado por mí:

Código Delphi [-]
type


   TPerformanceTime = Class(TObject)
  private
    FElapsed: Int64;
    FStart, FFinish, FFrec:Int64;
    function GetFElapsedTime: String;
    public
      procedure Start;
      procedure Finish;
      property ElapsedTime : String read GetFElapsedTime;

    end;
implementation

{ TPerformanceTime }

  const MiliSegundos = 1000;

procedure TPerformanceTime.Finish;
begin
  QueryPerformanceCounter(FFinish);
  FElapsed := (FFinish - FStart) * MiliSegundos div FFrec;
end;

function TPerformanceTime.GetFElapsedTime: String;
begin
  result := Format(' %d Milisegundos',[FElapsed]);
end;

procedure TPerformanceTime.Start;
begin
   QueryPerformanceFrequency(FFrec);
   QueryPerformanceCounter(FStart);
end;

Ejemplo de uso:
Código Delphi [-]
var Counter : TperformanceTime;
begin
  Counter := TPerformanceTime.Create;
  Counter.Start;
  // algoritmo a medir el tiempo;
  Counter.Finish;
  ShowMessage(Counter.ElapsedTime);
  Counter.Free;
end;

Como el cronómetro usado es del ordenador, no importa si nuestra aplicación se queda congelada.

Saludos

Bauhaus1975 30-06-2006 18:26:08

Muchas gracias. Voy a intentar lo que me has explicado.
Ya te comento si tengo algún problema.

Un saludo.

Arsenio 03-04-2009 22:41:28

Cita:

Empezado por Lepe (Mensaje 144561)
Con GetTickCount no necesitas un Timer. Aquí tienes un ejemplo sacado de Ians Marteens "midiendo el tiempo con precisión", adaptado por mí...

Muchas gracias Lepe, justo estaba buscando algo simple pero preciso para medir el tiempo, me vino muy bien tu clase, se agradece...

rgstuamigo 03-04-2009 22:58:58

Yo solo utilizaria la funcion TimeGetTime (ideal para lo que necesitas)de la unidad MMSystem ,mas o menos de esta manera:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var dwTiempo: DWord;
begin
    dwTiempo:=TimeGetTime;//aqui  se inicia
    //hago lo que tengo que hacer;
    ...
    ...
    ...
    //al final muestro el tiempo
   ShowMessage( 'Tiempo: '+IntToStr(TimeGetTime-dwTiempo)+' milisegundos' );
   //sencillo optimo y practico;):D
end;
Edito:Esto es sin Timer y sin ninguna Clase extra.;)
y es mas precisa que GetTickCount.

brandolin 03-04-2009 23:18:24

Hola, te recomiendo que en varias partes de tu codigo, por ejemplo dentro de un bucle, uses la instruccion "Applicattion.proccessmessage;"
Esta instruccion hace que windows procese los mensajes pendientes y da el efecto que la aplicacion no se congela. Asi se pueden ejecutar las instrucciones del timer.
Yo lo uso asi y me funciona.

rgstuamigo 03-04-2009 23:44:25

Cita:

Empezado por brandolin (Mensaje 343828)
Hola, te recomiendo que en varias partes de tu codigo, por ejemplo dentro de un bucle, uses la instruccion "Applicattion.proccessmessage;"
Esta instruccion hace que windows procese los mensajes pendientes y da el efecto que la aplicacion no se congela. Asi se pueden ejecutar las instrucciones del timer.
Yo lo uso asi y me funciona.

Apuntada tu sugerencia amigo Brandolin pero creo que haciendolo con un timer no es muy Optimo.;)
Saludos...

juanelo 04-04-2009 01:45:47

Aqtime es lo mejor que he visto y usado para medir tiempos de ejecucion y buscar cuellos de botella o procesos inecesariamente lentos.
Saluos

Bauhaus1975 08-04-2009 11:10:17

Pues me alegro que este post, con cuatro años de vida nos haya ayudado tanto.
Saludos.

viveba 24-11-2012 02:16:59

retomando este hilo...
 
Hola a todos.

Si alguien llega acá buscando respuestas a "MEDIR EL TIEMPO CON PRECISIÓN" igual que llegué yo, les comento que encontré la solución en:
http://arsenio-programa.blogspot.com...45989046264412

Sencillo, muy clarito, muy profesional, muy recomendable


La franja horaria es GMT +2. Ahora son las 04:27:19.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi