unit uTimeOpsMain;

{xDEFINE SPX_FREECREATE_VS_LIMPIAR}       //Mejor limpiar 3 a 1
{x$DEFINE INCJ_VS_J=J+1}                  //Mejor J=J+1 por apenas
{x$DEFINE DIV_VS_MULTPINV}                //Mejor MULTPINV 10 a 1
{x$DEFINE SINGLE_VS_DOUBLE}               //Iguales
{xDEFINE INSERTIONSORT_VS_COPYQUICKSORT}  //Mejor COPYQUICKSORT
{x$DEFINE REFERENCIAR_VS_USARVARIABLE}    //Referenciar es 1.3 veces mas rápido
{x$DEFINE ARRAY_VS_TLIST}                 //ARRAY es 2.9 veces mas rápido
{x$DEFINE GETTICKCOUNT_VS_NOW}             //GETTICKCOUNT es 50 veces mas rápido
{$DEFINE MULTIWRITE_VS_UNWRITE}            //UNWRITE es 5 veces mas rápido
{x$DEFINE SYSTEMRANDOM_VS_FDDPRANDOM}        //SYSTEMRANDOM es 190 veces mas rápido

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, uMipSimplex, xMatDefs, uAuxiliares, fddp;

{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
const
  tamanioArreglos = 100;
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
const
  nFilas = 50;
  nCols = 100;
{$ENDIF}

{$IFDEF ARRAY_VS_TLIST}
const
  tamLista = 10;

type
  TObj = class
    public
      Constructor Create;
      procedure procVacio;
  end;

  TDAOfObj = array of TObj;
{$ENDIF}

{$IFDEF MULTIWRITE_VS_UNWRITE}
const
  nNumeros = 1250;
  formatoReales = ffFixed;
{$ENDIF}

type
  TTimeOps = class(TForm)
    LT1: TLabel;
    LT2: TLabel;
    ETOp1: TEdit;
    ETOp2: TEdit;
    BComparar: TButton;
    LNIters: TLabel;
    ENIters: TEdit;
    LTOp1SobreTOp2: TLabel;
    LTOp2SobreTOp1: TLabel;
    ETOp1SobreETOp2: TEdit;
    ETOp2SobreTOp1: TEdit;
    ETFor: TEdit;
    LTFor: TLabel;
    BTemporizar: TButton;
    LT1Op1: TLabel;
    LT1Op2: TLabel;
    ET1Op1: TEdit;
    ET1Op2: TEdit;
    procedure BCompararClick(Sender: TObject);
    procedure BTemporizarClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  TimeOps: TTimeOps;

implementation

{$R *.dfm}

procedure TTimeOps.BCompararClick(Sender: TObject);
var
  ticksFor, ticksIni, ticksFin, frec: Int64;
  tOp1, tOp2: Double;
//  tIni, tOp1, tOp2, tFor: Double;
  nIters: Integer;
  i: Integer;
{$IFDEF SPX_FREECREATE_VS_LIMPIAR}
  spx: TMIPSimplex;
{$ENDIF}
{$IFDEF INCJ_VS_J=J+1}
  j: Integer;
{$ENDIF}
{$IFDEF DIV_VS_MULTPINV}
  res, val: Double;
{$ENDIF}
{$IFDEF SINGLE_VS_DOUBLE}
  resd: Double;
  ress: Single;
{$ENDIF}
{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
  arrayOrig, copia: TDAofNReal;
  j: Integer;
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
  val: Double;
  mat: array of TDAofNReal;
  filaj: TDAofNReal;
  j, k: Integer;
{$ENDIF}
{$IFDEF ARRAY_VS_TLIST}
  j: Integer;
  obj: TObj;
  lista: TList;
  arreglo: TDAOfObj;
{$ENDIF}
{$IFDEF GETTICKCOUNT_VS_NOW}
  tickCount: Cardinal;
  ahora: TDateTime;
{$ENDIF}
{$IFDEF MULTIWRITE_VS_UNWRITE}
  numeros: TDAOfNReal;
  j: Integer;
  fsal: TextFile;
{$ENDIF}
{$IFDEF SYSTEMRANDOM_VS_FDDPRANDOM}
  valor: NReal;
  sorteadorUniforme: Tf_ddpMadreUniformeRand3;
{$ENDIF}
begin
  nIters:= StrToInt(ENIters.Text);

  //Inicializaciones
{$IFDEF SPX_FREECREATE_VS_LIMPIAR}
  spx:= TMIPSimplex.Create_init( 50, 100, 20 -1, nil, nil);
{$ENDIF}
{$IFDEF INCJ_VS_J=J+1}
  j:= 0;
{$ENDIF}
{$IFDEF DIV_VS_MULTPINV}
  val:= 10;
  res:= 10;
{$ENDIF}
{$IFDEF SINGLE_VS_DOUBLE}
  resd:= 1;
  ress:= 1;
{$ENDIF}
{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
  SetLength(arrayOrig, tamanioArreglos);
  for j:= 0 to tamanioArreglos - 1 do
    arrayOrig[j]:= Random(100);
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
  val:= 0;
  SetLength(mat, nFilas);
  for j:= 0 to high(mat) do
  begin
    SetLength(mat[j], nCols);
    for k:= 0 to high(mat[j]) do
      mat[j][k]:= random(1000);
  end;
{$ENDIF}
{$IFDEF ARRAY_VS_TLIST}
  SetLength(arreglo, tamLista);
  lista:= TList.Create;
  for j:= 0 to tamLista - 1 do
  begin
    obj:= TObj.Create;
    arreglo[j]:= obj;
    lista.Add(obj);
  end;
{$ENDIF}
{$IFDEF GETTICKCOUNT_VS_NOW}
  tickCount:= 0;
  ahora:= 0;
{$ENDIF}
{$IFDEF MULTIWRITE_VS_UNWRITE}
  SetLength(numeros, nNumeros);
  for j:= 0 to high(numeros) do
    numeros[j]:= Random() * MaxInt;
  AssignFile(fsal, 'fsal.txt');
  rewrite(fsal);
{$ENDIF}
{$IFDEF SYSTEMRANDOM_VS_FDDPRANDOM}
  sorteadorUniforme:= Tf_ddpMadreUniformeRand3.Create(0);
{$ENDIF}

  QueryPerformanceFrequency(frec);
  QueryPerformanceCounter(ticksIni);
  for i:= 1 to nIters do
  begin
    //Nada
  end;
  QueryPerformanceCounter(ticksFin);
  ticksFor:= ticksFin - ticksIni;
  ETFor.Text:= FloatToStrF(ticksFor / frec, ffFixed, 8, 3);

  QueryPerformanceCounter(ticksIni);
  for i:= 1 to nIters do
  begin
  //Operación 1
{$IFDEF SPX_FREECREATE_VS_LIMPIAR}
		spx.Free;
    spx:= TMIPSimplex.Create_init( 50, 100, 20 -1, nil, nil);
{$ENDIF}
{$IFDEF INCJ_VS_J=J+1}
    inc(j);
{$ENDIF}
{$IFDEF DIV_VS_MULTPINV}
    res:= 1 / val;
{$ENDIF}
{$IFDEF SINGLE_VS_DOUBLE}
    ress:= ress + 0.894;
    ress:= ress * 1.5847;
    ress:= ress / 1.987319;
{$ENDIF}
{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
    copia:= InsertionSort_Creciente(arrayOrig);
    SetLength(copia, 0);
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
    for j:= 0 to high(mat) do
      for k:= 0 to high(mat[j]) do
        val:= mat[j][k];
{$ENDIF}
{$IFDEF ARRAY_VS_TLIST}
    for j:= 0 to tamLista -1 do
      arreglo[j].procVacio;
{$ENDIF}
{$IFDEF GETTICKCOUNT_VS_NOW}
    tickCount:= GetTickCount;
{$ENDIF}
{$IFDEF MULTIWRITE_VS_UNWRITE}
    for j:= 0 to high(numeros) do
      write(fsal, #9, FloatToStrF(numeros[j], formatoReales, 8, 2));
    writeln(fsal);
{$ENDIF}
{$IFDEF SYSTEMRANDOM_VS_FDDPRANDOM}
    System.RandSeed:= i;
    valor:= System.Random;
{$ENDIF}
  end;
{$IFDEF MULTIWRITE_VS_UNWRITE}
  CloseFile(fsal);
{$ENDIF}

  QueryPerformanceCounter(ticksFin);
  tOp1:= (ticksFin - ticksIni - ticksFor) / frec;
  ETOp1.Text:= FloatToStrF(tOp1, ffFixed, 8, 3);
  ET1Op1.Text:= FloatToStrF(tOp1 * 1000000 / nIters, ffFixed, 8, 3 );

{$IFDEF MULTIWRITE_VS_UNWRITE}
  AssignFile(fsal, 'fsal.txt');
  rewrite(fsal);
{$ENDIF}

  QueryPerformanceCounter(ticksIni);
{$IFDEF DIV_VS_MULTPINV}
  val:= 1 / val;
{$ENDIF}
  for i:= 1 to nIters do
  begin
  //Operación 2
{$IFDEF SPX_FREECREATE_VS_LIMPIAR}
    spx.limpiar;
{$ENDIF}
{$IFDEF INCJ_VS_J=J+1}
    j:= j + 1;
{$ENDIF}
{$IFDEF DIV_VS_MULTPINV}
    res:= 1 * val;
{$ENDIF}
{$IFDEF SINGLE_VS_DOUBLE}
    resd:= resd + 0.894;
    resd:= resd * 1.5847;
    resd:= resd / 1.987319;
{$ENDIF}
{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
    SetLength(copia, Length(arrayOrig));
    for j:= 0 to high(arrayOrig) do
      copia[j]:= arrayOrig[j];
    QuickSort_Creciente(copia);
    SetLength(copia, 0);
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
    for j:= 0 to high(mat) do
    begin
      filaj:= mat[j];
      for k:= 0 to high(filaj) do
        val:= filaj[k];
    end;
{$ENDIF}
{$IFDEF ARRAY_VS_TLIST}
    for j:= 0 to tamLista -1 do
      TObj(lista[j]).procVacio;
{$ENDIF}
{$IFDEF GETTICKCOUNT_VS_NOW}
    ahora:= now;
{$ENDIF}
{$IFDEF MULTIWRITE_VS_UNWRITE}
    writeln(fsal, TDAOfNRealToTabbedString(numeros, 8, 2));
{$ENDIF}
{$IFDEF SYSTEMRANDOM_VS_FDDPRANDOM}
    sorteadorUniforme.Reiniciar(i);
    valor:= sorteadorUniforme.rnd;
{$ENDIF}
  end;

{$IFDEF MULTIWRITE_VS_UNWRITE}
  CloseFile(fsal);
{$ENDIF}
  QueryPerformanceCounter(ticksFin);
  tOp2:= (ticksFin - ticksIni - ticksFor) / frec;
  ETOp2.Text:= FloatToStrF(tOp2, ffFixed, 8, 3);
  ET1Op2.Text:= FloatToStrF(tOp2 * 1000000 / nIters, ffFixed, 8, 3 );

  //Liberaciones
{$IFDEF SPX_FREECREATE_VS_LIMPIAR}
  spx.Free;
{$ENDIF}
{$IFDEF INCJ_VS_J=J+1}
  writeln(j);
{$ENDIF}
{$IFDEF DIV_VS_MULTPINV}
  writeln(res);
{$ENDIF}
{$IFDEF SINGLE_VS_DOUBLE}
  writeln(resd);
  Writeln(ress);
{$ENDIF}
{$IFDEF INSERTIONSORT_VS_COPYQUICKSORT}
  SetLength(arrayOrig, 0);
{$ENDIF}
{$IFDEF REFERENCIAR_VS_USARVARIABLE}
  writeln(val);
  for j:= 0 to high(mat) do
    SetLength(mat[j], 0);
  SetLength(mat, 0);
{$ENDIF}
{$IFDEF ARRAY_VS_TLIST}
  for j:= 0 to tamLista -1 do
    arreglo[j].Free;
  SetLength(arreglo, 0);
  lista.Free;
{$ENDIF}
{$IFDEF GETTICKCOUNT_VS_NOW}
  writeln(tickCount, ahora);
{$ENDIF}
{$IFDEF MULTIWRITE_VS_UNWRITE}
  SetLength(numeros, 0);
  DeleteFile('fsal.txt');
{$ENDIF}

  if (tOp1 = 0) or (tOp2 = 0) then
  begin
    ShowMessage('El número de iteraciones no permite tomar una medida efectiva.' +
                'Incrementelo y vuelva a intentarlo.');
  end
  else
  begin
    ETOp1SobreETOp2.Text := FloatToStrF(tOp1 / tOp2, ffFixed, 8, 3);
    ETOp2SobreTOp1.Text := FloatToStrF(tOp2 / tOp1, ffFixed, 8, 3);
  end;
end;

{$IFDEF ARRAY_VS_TLIST}
Constructor TObj.Create;
begin
  inherited Create;
end;

procedure TObj.procVacio;
begin

end;
{$ENDIF}

procedure TTimeOps.BTemporizarClick(Sender: TObject);
var
  ticksIni, ticksFin, frec64, ticksFor: Int64;
  i: Integer;
  nIters: Integer;
begin
  nIters:= StrToInt(ENIters.Text);

  QueryPerformanceFrequency(frec64);
  QueryPerformanceCounter(ticksIni);
  for i:= 0 to nIters - 1 do
  begin
    //Nada
  end;
  QueryPerformanceCounter(ticksFin);
  ticksFor:= ticksFin - ticksIni;
  ETFor.Text:= FloatToStrF(ticksFor / frec64, ffFixed, 8, 3);

  QueryPerformanceCounter(ticksIni);
  for i:= 0 to nIters - 1 do
  begin
//    fddp.random;
  end;
  QueryPerformanceCounter(ticksFin);
  ETOp1.Text:= FloatToStrF((ticksFin - ticksIni) / frec64, ffFixed, 8, 3);
end;

end.
