Cómo acelerar 10 veces los bucles "For" con Delphi





Para conseguir que los bucles for se ejecuten hasta 10 veces más rapido hay que utilizar PPI (Parallel Programming Library) y si no se lo creen, ejecuten el siguiente código:


Bucle for como se hace habitualmente:


uses
  System.Threading, // Parallel Programming Library
  System.Diagnostics; // TStopwatch

// ...




procedure TForm1.btnForLoopRegularClick(Sender: TObject);
var sw: TStopwatch; i: Integer;
begin
  sw := TStopwatch.StartNew;
  for i := 0 to 99 do
    Sleep(10);
  sw.Stop;
  Label1.Text := sw.ElapsedMilliseconds.ToString + 'ms';
end;

Ahora el mismo bucle utilizando PPI


procedure TForm1.btnForLoopParallelClick(Sender: TObject);
var sw: TStopwatch; i: Integer;
begin
  sw := TStopwatch.StartNew;
  TParallel.For(0, 99, procedure(i: integer)
  begin
    Sleep(10);
  end);
  sw.Stop;
  Label1.Text := sw.ElapsedMilliseconds.ToString + 'ms';
end;

En el primer caso el tiempo de ejecución es 1038 msegs y en el segundo caso de 117 msegs., como ven el incremento de velocidad está en un rango de 10 veces aproximadamente.
Espero que este truco les sea útil y que lo utilicen en sus programas. 


También te puede interesar

Ejemplos de programación paralela 
 

3 comentarios:

  1. Si haces un bucle repitiendo 100 veces un retraso de 10 ms debería tardar 100*10= 1000ms que es el tiempo indicado al principio.
    Si en lugar de tardar eso, tarda 10 veces menos, es que hay algo mal, ¿no te parece?
    En lugar de 10 ms por bucle, usa 1 ms, o sea, no ejecuta el sleep.

    ResponderEliminar
  2. Hola, si entiendo bien el funcionamiento del TParallel.For se ejecuta en threads el código de cada iteración, con lo que el cálculo del tiempo no es correcto si solo tienes en cuenta el tiempo entre el inicio y el fin del for, ya que por detrás tienes otros hilos ejecutándose que pueden acabar su ejecución vete a saber cuando.

    ResponderEliminar
  3. Tengo muchas dudas sobre el funcionamiento del TParallel.For y quisiera saber si pudiera bajar el tiempo de un proyecto que hago el cual cuenta aproximadamente con 88000 registros y tarda en correr 1 hora con 5 minutos.

    A continuaciòn pongo ejemplo:
    while (not Datos.Activos.Eof) do
    begin
    for ddi:=1 to MaxDensidad do
    begin
    Densidad:=ddi; DensGlobal:=ddi;
    Desglosa_GA; //Este procedimiento lee la base de datos
    Y dentro del for se hacen màs càlculos....
    end;
    end;

    ResponderEliminar