Delphi XE2 nuovi test

Delphi XE2 altri test!

Seconda serie di test su Delphi XE2 e Firemonkey… Vi anticipo che i risultati non sono affatto buoni. Sono già al 3 fazzoletto zuppo di lacrime 😦
Che dire, uno dei cavalli di battaglia della pubblicità di Firemonkey è stato “More power and performance… with native CPU performance and GPU powered visuals on PC” Per cui mi sono detto “e stressiamo questa GPU!!!”

Dato che il tempo è tiranno è il lavoro mi ruba anche l’anima diciamo che il tentativo di stress della GPU si limita al 2D e forse non si stressa neanche molto… ma provare non nuoce.

Cosa ho fatto? Ho creato 3 diverse versioni dello stesso programma, un thread secondario che disegna 1.000 rettangoli filled (cioè colorati internamente) in ambiente VCL standard (quello che viene definito lento e vecchio), in ambiente Direct 2D (quindi veloce e ottimizzato per windows) e con Firemonkey (da quello che racconta Embarcadero dovrebbe usare Direct 2D in ambiente Windows).

Il codice sorgente, riporto solo quello del thread è per la VCL questo:

constructor Draw.Create(ext_Layout: TImage);
begin
  inherited Create(true);

  Layout1 := ext_Layout;

  arrayColor[1] := TColorRec.Aliceblue;
...
...
  arrayColor[154] := TColorRec.Yellowgreen;

end;

procedure Draw.Execute;
var
  i: integer;
  dStartTime, dEndTime: TDateTime;

begin

  dStartTime := now;
  iShape := 1;
  for i := 1 to MAX_NUM_OF_SHAPES do
  begin
    synchronize(aggiorna);
  end;
  dEndTime := now;

  showmessage('Inizio   : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dStartTime) + #13#10 +
              'Fine     : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dEndTime) + #13#10 +
              'Trascorso: ' + formatDateTime( 'hh:nn:ss:zzz', dEndTime - dStartTime) + #13#10);
end;

procedure Draw.aggiorna;
var
  iColor, iXCoord, iYCoord: integer;

begin
  Randomize;
  iColor := RandomRange(1, 154);
  iXCoord := RandomRange(0, Layout1.Width);
  iYCoord := RandomRange(0, Layout1.Height);

  Layout1.Canvas.Brush.Color := arrayColor[iColor];

  Layout1.Canvas.Rectangle(iXCoord, iYCoord, 250, 200);
  inc(iShape);
end;

Per il direct 2d questo:

constructor Draw.Create(ext_Layout: TImage);
begin
  inherited Create(true);

  Layout1 := ext_Layout;

  arrayColor[1] := TColorRec.Aliceblue;
...
...
  arrayColor[154] := TColorRec.Yellowgreen;

end;

procedure Draw.Execute;
var
  i: integer;
  dStartTime, dEndTime: TDateTime;
  iColor, iXCoord, iYCoord: integer;

begin

  dStartTime := now;
  INumRect := 1;
  for i := 1 to MAX_NUM_OF_SHAPES do
  begin
    iColor := RandomRange(1, 154);
    iXCoord := RandomRange(0, imgView.Width);
    iYCoord := RandomRange(0, imgView.Height);
    arrayAssignedColor[i] := arrayColor[iColor];
    arrayRect[i] := Rect(iXCoord, iYCoord, 250, 200);
  end;

  synchronize(aggiorna);

  dEndTime := now;

  showmessage('Inizio   : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dStartTime) + #13#10 +
              'Fine     : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dEndTime) + #13#10 +
              'Trascorso: ' + formatDateTime( 'hh:nn:ss:zzz', dEndTime - dStartTime) + #13#10);
end;

procedure Draw.aggiorna;
var
  j: integer;

begin

  Layout1 := TDirect2DCanvas.Create(imgView.Canvas, imgView.ClientRect);

  Layout1.BeginDraw;

  Layout1.Pen.Color := clBlack;
  Layout1.Pen.Style := psSolid;

  for j := 1 to MAX_NUM_OF_SHAPES do
  begin
    Layout1.Brush.Color := arrayAssignedColor[j];
    Layout1.FillRect(arrayRect[j]);
  end;

  Layout1.EndDraw;
  Layout1.free;
end;

Per Firemonkey quest’ultimo:

constructor Draw.Create(ext_Layout: TLayout);
begin
  inherited Create(true);

  Layout1 := ext_Layout;
  Test := TRectangle.Create(Layout1);

  arrayColor[1] := TAlphaColorRec.Alpha;
	arrayColor[2] := TAlphaColorRec.Aliceblue;

...
...
  arrayColor[154] := TAlphaColorRec.Yellowgreen;

end;

procedure Draw.Execute;
var
  i: integer;
  dStartTime, dEndTime: TDateTime;

begin

  dStartTime := now;
  iShape := 1;
  for i := 1 to MAX_NUM_OF_SHAPES do
  begin
    synchronize(aggiorna);
  end;
  dEndTime := now;

  showmessage('Inizio   : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dStartTime) + #13#10 +
              'Fine     : ' + formatDateTime( 'dd-mm-yyyy hh:nn:ss:zzz', dEndTime) + #13#10 +
              'Trascorso: ' + formatDateTime( 'hh:nn:ss:zzz', dEndTime - dStartTime) + #13#10);
end;

procedure Draw.aggiorna;
var
  iColor, iXCoord, iYCoord: integer;

begin
    Layout1.Canvas.BeginScene;
    with TRectangle.Create(Layout1) do
    begin

      iColor := RandomRange(1, 154);
      iXCoord := RandomRange(0, trunc(Layout1.Width));
      iYCoord := RandomRange(0, trunc(Layout1.Height));

      parent := Layout1;
      Fill.Color := arrayColor[iColor];
      Width := 250;
      height := 200;
      Position.X := iXCoord;
      Position.Y := iYCoord;
      //RotationAngle := iShape - 1;
      RotationAngle := 0;
      inc(iShape);
    end;

    Layout1.Canvas.EndScene;
end;

Compilo ed eseguo! Di seguito il risultato per la VCL:

Questo è quello di direct2D:

Questo è FireMonkey:

Anche questa prova è impietosa…

VCL        299 ms
Direct 2D   45 ms
Firemonkey  35,17 s

E’ da notare inoltre che nonostante io abbia definito un frame di visualizzazione i rettangoli del test con firemonkey sono andati a ricoprire anche il bottone che non è più visibile ma è nella stessa posizione degli altri 2 test.
Riguardo al consumo di CPU facendo un confronto spannometrico e usando il gestore di attività di windows ottengo un picco di:

VCL        6%   CPU
Direct 2D  1%   CPU
Firemonkey 3-8% CPU

Per cui Firemonkey ha richiesto più CPU di tutti gli altri con oscillazioni dal 3 all’8 percento. Insomma un disastro… per scrupolo manderò ancora queste prove ad Embarcadero, caso mai non avendo ne help ne documentazione abbia sbagliato ad usare Firemonkey, se ci saranno novità vi racconterò, ma sto ancora aspettando risposta alla mia ultima mail… di 3 mesi fa!

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • juhan  Il 19 gennaio 2012 alle 14:18

    Solo una domanda, anzi qualche domanda:
    Farai ancora una pagina di conclusione in cui mi/ci dici se vale la pena di insistere con quello che era il nostro ambiente preferito? O quali sono le alternative?
    E bisogna proprio insistere con Windows? (OK, questa non vale)

  • dikiyvolk  Il 19 gennaio 2012 alle 17:37

    Ciao Juhan,

    Sono in contatto con Embarcadero… che sta analizzando il mio codice, ho mandato i sorgenti stamane e mi faranno saperre. Per cui appena avrò notizie o altra carne da mettere sul fuoco ti/vi farò sapere.

  • Paolo Ingraito  Il 21 gennaio 2012 alle 13:10

    Ciao, sono al momento ancora un principiante di Firemonkey, e di Delphi 😛 ; però, in un test che ho fatto, mi sono reso conto l’oggetto TRectangle in Firemonkey è già un oggetto piuttosto complesso, che deriva da un TControl. La creazione o la modifica di grandi numeri di questi oggetti (che fra l’altro occupano molta memoria e CPU) è sicuramente più dispendiosa rispetto a gestire una figura rettangolare base su una Canvas. Cavolo, ma da quando sono tornato a Delphi sento la mancanza di una bella community in cui discutere di queste cose.

    • Dikiyvolk  Il 21 gennaio 2012 alle 14:04

      Ciao Paolo,

      Ho pensato anche io che la creazione degli oggetti fosse la causa delle divergenze dei tempi. E’ ho impiegato un po’ del mio tempo a cercare forme di disegno alternative… senza trovare nulla. Però la risposta definitiva l’ho avuta da Embarcadero in una mail di cui ancora non ho raccontato 🙂 e di cui aspetto gli approfondimenti.
      Comunque mi dicono:
      “- A TRectangle is a primitive shape and should be drawn instantly by the
      GPU, not the CPU. So we that is certainly interesting to hear and for us
      to try.”
      La cosa simpatica è quel “should be drawn instantly” e poi il successivo “by the
      GPU, not the CPU”, mi sembrano un po’ confusi anche loro… 🙂
      Se vuoi ti mando il mio codice per intero, sono 84K zippati.

      Comunity su delphi non ne conosco, una volta seguivo i newsgroup di Wintech, poi sono diventato “grande” 🙂 o meglio sono passati gli anni e ho scoperto che alcuni MITI dell’informatica ne sapevano molto meno di me sui progetti reali e con alcuni newsgroup si finiva come alla crociate 🙂 una guerra di religione.
      Io adoro delphi (un po’ di più il c++) è veloce è facile e come ricordava Juhan lo “usava” un certo Wirth 🙂
      Se hai comunque domande o altro puoi scrivermi qui sul blog. Accetto tranquillamente suggerimenti e proposte 🙂 e anche gli schiaffi sulle orecchie se sbaglio!

      Ciao, ciao.

  • Paolo Ingraito  Il 21 gennaio 2012 alle 16:21

    Se ti va, volentieri; in particolare mi piacerebbe creare una mini-library di componenti Firemonkey, che si potrebbero utilizzare per delle applicazioni personali. Ho creato alcune componenti, che mi piacerebbe condividere con te; sono essenzialmente dei knob e degli slider totalmente Bitmap, che utilizzano dei frame da un file di risorse. Vediamo un po’ ti mando una mail con delle cose e mi dici se le trovi interessanti. Il tutto è perchè ho in mente di costruirmi un Synth in Delphi, ricostrumendomi un’intefaccia che mi ero creato nel linguaggio di scripting di Kontakt (Native Instruments) e implementando la parte audio dalla libreria BASS.
    Ti mando il file, dimmi cosa ne pensi (non so se serve anche il file BPL, o se questo viene “dedotto dal File di progetto”). Comunque mi sembra che la maggior parte dei programmatori in Delphi faccia database e poche cose a “basso livello”, ambito che di solito mi sembra più tipico del C++. Ma io adoro Delphi come linguaggio.

    Se vorrai passarmi il tuo codice sarò lietissimo di dargli un occhio.
    Ora sto cercando di emulare una specie di tabella a barre verticali, che siano ridisegnabili col mouse, che rappresentano in sostanza i valori di un array, tipo questa qua:

    L’ho fatta con dei rettangoli innestati dentro altri rettangoli, ma quando i rettangoli diventano troppi mi va tutto in crisi (che è un po’ il problema che devi avere avuto tu) ^^
    Allora pensavo di rifarla disegnandola direttamente su una TImage.

    (ps.non trovo il tuo indirizzo di mail)
    Ciao Ciao,
    Paolo

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: