Archivo mensual: septiembre 2021

TStopWatch y cómo medir tiempos con alta precisión con Delphi

Las versiones modernas de Delphi cuentan con la unidad System.Diagnostics que implementa la clase TStopWatch, un cronómetro de alta precisión con el que podemos medir fácilmente el desempeño del código que escribimos, con soporte multiplataforma.

TStopWatch es un registro que tiene métodos para iniciar, pausar y resetear el cronómetro (muy similar a los botones que encontramos en el cronómetro de pulsera promedio).

Cuando digo alta precisión, hablamos de que la resolución del cronómetro suele estar en el orden de los nano-segundos o incluso fracciones de nanosegundo (esta puede variar de un procesador a otro). En mi equipo de desarrollo actual (Corei7 8va Generación/Windows 10), el menor tiempo que he podido medir es de 0.1 nanosegundos, la idea básica sería algo como:

procedure TForm3.Button1Click(Sender: TObject);
var
  SW: TStopwatch;
begin
  SW := TStopwatch.Create;
  SW.Start;
  SW.Stop;
  Memo1.Lines.Add(Format('Ticks: %d, Frequency: %d', [SW.ElapsedTicks, sw.Frequency]));
  Memo1.Lines.Add(SW.Elapsed.ToString);
end;

Ya con esta idea básica podemos medir, entonces, el tiempo que tarde cualquier fragmento de código, por ejemplo:

procedure TForm3.Button1Click(Sender: TObject);
var
  SW: TStopwatch;
  I, J: Integer;
begin
  J := 0;
  SW := TStopwatch.Create;
  SW.Start;
  for I := 1 to 1000000 do
    J := J + I;
  SW.Stop;
  Memo1.Lines.Add(Format('J: %d', [J]));
  Memo1.Lines.Add(Format('Ticks: %d, Frequency: %d, ms: %d, ns: %.6f', [SW.ElapsedTicks, sw.Frequency, SW.ElapsedMilliseconds, SW.ElapsedTicks/sw.Frequency*1000000]));
  Memo1.Lines.Add(SW.Elapsed.ToString);
end;
Resultados de la ejecución del código

Pensando como bibliotecarios, podemos declarar una función que se encargue de realizar la medición de cualquier código por nosotros, por ejemplo:

function MedirTiempoDe(Proc: TProc): TTimeSpan;
var
  SW: TStopwatch;
begin
  SW := TStopwatch.StartNew;
  Proc();
  SW.Stop;
  Result := SW.Elapsed;
end;

En una futura entrada veremos como crear una biblioteca de medición de tiempos robusta basados en TStopWatch.