Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-06-2006
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 19
Bauhaus1975 Va por buen camino
Unhappy 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.
Responder Con Cita
  #2  
Antiguo 29-06-2006
Avatar de Sotrono
Sotrono Sotrono is offline
Miembro
 
Registrado: abr 2004
Ubicación: Buenos Aires - Argentina
Posts: 396
Poder: 20
Sotrono Va por buen camino
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..
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!!

Última edición por Sotrono fecha: 29-06-2006 a las 20:03:08.
Responder Con Cita
  #3  
Antiguo 29-06-2006
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 19
Bauhaus1975 Va por buen camino
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.
Responder Con Cita
  #4  
Antiguo 29-06-2006
Avatar de Sotrono
Sotrono Sotrono is offline
Miembro
 
Registrado: abr 2004
Ubicación: Buenos Aires - Argentina
Posts: 396
Poder: 20
Sotrono Va por buen camino
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.
Responder Con Cita
  #5  
Antiguo 30-06-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
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
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #6  
Antiguo 30-06-2006
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 19
Bauhaus1975 Va por buen camino
Muchas gracias. Voy a intentar lo que me has explicado.
Ya te comento si tengo algún problema.

Un saludo.
Responder Con Cita
  #7  
Antiguo 03-04-2009
Avatar de Arsenio
Arsenio Arsenio is offline
Miembro
 
Registrado: oct 2006
Posts: 13
Poder: 0
Arsenio Va por buen camino
Cita:
Empezado por Lepe Ver Mensaje
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...
Responder Con Cita
  #8  
Antiguo 03-04-2009
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Thumbs up

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
end;
Edito:Esto es sin Timer y sin ninguna Clase extra.
y es mas precisa que GetTickCount.
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7

Última edición por rgstuamigo fecha: 04-04-2009 a las 00:14:13.
Responder Con Cita
  #9  
Antiguo 04-04-2009
brandolin brandolin is offline
Miembro
 
Registrado: jul 2003
Ubicación: Mendoza
Posts: 324
Poder: 21
brandolin Va por buen camino
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.
Responder Con Cita
  #10  
Antiguo 04-04-2009
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Wink

Cita:
Empezado por brandolin Ver Mensaje
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...
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7
Responder Con Cita
  #11  
Antiguo 04-04-2009
Avatar de juanelo
juanelo juanelo is offline
Miembro
 
Registrado: sep 2007
Posts: 1.082
Poder: 18
juanelo Va por buen camino
Aqtime es lo mejor que he visto y usado para medir tiempos de ejecucion y buscar cuellos de botella o procesos inecesariamente lentos.
Saluos
__________________
Ya tengo Firma!
Responder Con Cita
  #12  
Antiguo 08-04-2009
Bauhaus1975 Bauhaus1975 is offline
Miembro
 
Registrado: may 2005
Ubicación: Málaga
Posts: 135
Poder: 19
Bauhaus1975 Va por buen camino
Pues me alegro que este post, con cuatro años de vida nos haya ayudado tanto.
Saludos.
Responder Con Cita
  #13  
Antiguo 24-11-2012
viveba viveba is offline
Miembro
 
Registrado: nov 2006
Posts: 24
Poder: 0
viveba Va por buen camino
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
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
problemas en tiempo de ejecución Nelly Varios 4 05-04-2006 20:25:53
Problemas al tratar de crear varios componentes en tiempo de ejecucion ilichhernandez Conexión con bases de datos 2 13-11-2005 20:03:26
Cómo medir en unidades de tiempo? Gabriel2 Varios 2 31-10-2005 16:51:24
Problema con un Timer en tiempo de Ejecucion santiellupin OOP 4 15-05-2004 17:21:37
abrir BD mdb usando ADOconnections en tiempo de ejecución viajero2015 Conexión con bases de datos 3 25-09-2003 02:39:05


La franja horaria es GMT +2. Ahora son las 10:06:10.


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
Copyright 1996-2007 Club Delphi