[ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopieren?

Rund um die LCL und andere Komponenten
Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

[ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von Soner »

Wie kann man ein Bild übernehmen ohne zu kopieren?

Ich habe folgenden code:

Code: Alles auswählen

 
  //Pic : TPicture; wird global erstellt
  //GetDialogIcon liefert TCustomBitmap  (aus Dialogs.pp)
 
  Pic.Graphic:=GetDialogIcon(mtConfirmation);
 


Das verursacht Speicherleck, weil bei der Zuweisung ein neues Bild erstellt und Daten von der rechten Seite kopiert wird. (TPicture.SetGraphic wird aufgerufen)
Das Bild das GetDialogIcon zurückliefert wird nirgendwo freigegeben.(Nach dem Programmende wird der Speicherleck von "Heaptr-Unit" angezeigt.).
Man könnte mit einem temporären Bild arbeiten, aber das macht das Programm unnötig langsam.
Um das Problem zu lösen habe ich Graphics-Unit verändert, nur damit wird meine Änderungsliste immer länger und das macht Aktualisierung von Lazarus/fpc schwierig.
Zuletzt geändert von Soner am So 29. Okt 2017, 13:38, insgesamt 1-mal geändert.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von Mathias »

Ist dies etwa das selbe Problem, wie mit der Funktion FindAllFiled ?

Da würde eine temporäre Variable von TGrapics genügen, aber ohne Create.
Und nach der Übergabe, dann mit Free freigeben.

Wäre ein Versuch.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von Soner »

Das Problem mit FindAllFiled kenne ich nicht.

Hier gibt es auch kein Problem, die Codezeile:
Pic.Graphic:=GetDialogIcon(mtConfirmation);
macht auch was es machen soll. Es wird von rechts nach links kopiert.
Ich wollte nur vermeiden, dass es unnötig Kopie angelegt wird, wenn es auch direkt übernommen werden kann.
Da dieses Vorgehen bei großen Bildern auf Lasten von Performance geht, dachte ich, dass es irgendjemand so etwas gebraucht hat und es ein funktion schon dafür gibt.

Ich habe für mich nach Vorbild von TPicture.SetGraphic neue Funktion gebastelt:

Code: Alles auswählen

procedure TPicture.SetGraphicDirect(Value: TGraphic); 
begin
  if (Value=FGraphic) then exit;
 
  FGraphic.Free;
  FGraphic := Value;
  FGraphic.OnChange := @Changed;
  FGraphic.OnProgress := @Progress;
  Changed(Self);
end;


Vielleicht sollte man so etwas in die offizielle LCL aufnehmen.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von wp_xyz »

Es gibt ein paar Grundregeln, die ich mir für's objekt-orientierte Programmieren einverleibt habe. Eine davon (die auch für's tägliche Leben gilt): Wer etwas gemacht hat, räumt es auch auf.

Dein Code verstößt dagegen. In der Routine, die GetDialogIcon aufgerufen hat, wurde das Icon erzeugt; das Aufräumen wird aber delegiert an das Picture. Dein Code ist zwar bequem und irgendwie auch logisch, in dem Abweichen von der Aufräum-Regel sehe ich dagegen Probleme, weil man erst den Sourcecode studieren muss, um zu erkennen, dass sich das TPicture um das Bitmap kümmert. Auch in der Methode GetDialogIcon ist man von einer Regel abgewichen, und das hat zu dem vom dir geschilderten Problem geführt. Nämlich: Man sollte am Prozedurnamen erkennen, dass etwas erzeugt wird, damit man weiß, dass man es aufräumen muss. Das ist das eigentliche Problem: hieße die Funtion "CreateDialogIcon" hättest du den Code im 1.Post wahrscheinlich nie geschrieben.

Dann habe ich noch ein generelles Problem mit Funktionen, die etwas erzeugen und es als Funktionswert zurückgeben; denn man kann jede Funktion aufrufen, ohne den Funktionswert zu verwenden. Aber diese Diskussion hatten wir schon mal. (siehe "FindAllFiles"-Problematik).

Leider kann man das nicht ändern. Ich würde kurz und schmerzlos, wie Mattias schon sagte, eine Zwischenvariable einführen, so dass man das von GetDialogIcon erzeugte Projekt wieder beseitigen kann:

Code: Alles auswählen

var
  dlgIcon: TCustomBitmap;
begin
  dlgIcon := GetDialogIcon(mtConfirmation);
  try
    Pic.Graphic := dlgIcon;
  finally
    dlgIcon.Free;
  end;

P.S.
Die mit Lazarus/FPC ausgelieferten Units würde ich in meiner lokalen Kopie nie verändern, weil du langfristig eine Riesenarbeit hast, aktuell zu bleiben. Die paar Zeilen oben mehr sind mit Sicherheit schneller geschrieben als nach jedem Lazarus/FPC-Update manuell die eigenen Änderungen einzupflegen.

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von Soner »

wp_xyz hat geschrieben:P.S.
Die mit Lazarus/FPC ausgelieferten Units würde ich in meiner lokalen Kopie nie verändern, weil du langfristig eine Riesenarbeit hast, aktuell zu bleiben. Die paar Zeilen oben mehr sind mit Sicherheit schneller geschrieben als nach jedem Lazarus/FPC-Update manuell die eigenen Änderungen einzupflegen.

Es gibt nicht um ein paar Zeilen mehr tippen, es geht performance. Wenn Ich es bei :

Code: Alles auswählen

var
  dlgIcon: TCustomBitmap;
begin
  dlgIcon := GetDialogIcon(mtConfirmation);
  try
    Pic.Graphic := dlgIcon;
  finally
    dlgIcon.Free;
  end;

belassen würde, dann könnte ich nicht schlafen :D , weil es unnötige doppelte Arbeit ist, die vermieden werden kann.

Ich habe schon einiges geändert am meisten bei Lazreport und Stringgrid/DBGrid. Ohne diese Änderungen wäre mein Programm von mindere Qualität.
Das tolle bei Lazarus/fpc ist ja, dass man alles ändern kann. Ist das nicht der Sinn von Open-Source.
Z.B. sowohl bei Delphi als auch bei Lazarus sind die Initialwerte für TComboBox.DropDownCount immer 7. Ein Relikt aus 640x480 Monitorauflösungszeiten.
Entweder kann man jetzt in allen Programmen überall wo TCompobox, Stringgrid/DBGrid(für Dropdownlist), Lookuplisten, Valuelist gibt, diesen Wert ändern oder man ändert direkt einmalig bei lcl in 6 Stellen dann hat man es überall automatisch bessere Liste. Ich hab's 24 gemacht. Jetzt muß ich auch in der IDE nicht mehr an diesen Stellen scrollen. Oder bei Lazreport-Designer ist die Property-Editor sehr klein, Ich habe es einfach "links-aligned" gemacht und jetzt kann man damit sehr kompfortabel arbeiten. Und bei DBGrid habe ich die Indikatorspalte für Multiselect verwendet, die Benutzer freuen sich drauf.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Wie kann man ein Bild übernehmen ohne zu kopieren?

Beitrag von m.fuchs »

Soner hat geschrieben:Ich habe schon einiges geändert am meisten bei Lazreport und Stringgrid/DBGrid. Ohne diese Änderungen wäre mein Programm von mindere Qualität.
Das tolle bei Lazarus/fpc ist ja, dass man alles ändern kann. Ist das nicht der Sinn von Open-Source.

Die Frage ist ja: wie pflegst du die Änderungen mit bei neuen Version von Lazarus?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von wp_xyz »

Das sind doch alles sehr sinnvolle Änderungen. Warum schreibst du nicht einen BugReport dafür? Wenn deine Wünsche ins Produkt einfließen, haben alle etwas davon und du musst dich nicht mehr um deine eigene Aktualisierung kümmern. Das ist das allerschönste an OpenSource!

Zu dem angeblichen Performance-Problem: Wenn es in deinem Programm zu einem Speicherengpass kommt, weil ein Bild kurzfristig zweimal im Speicher verhanden ist, hast du eh schon verloren.

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von Soner »

m.fuchs hat geschrieben:Die Frage ist ja: wie pflegst du die Änderungen mit bei neuen Version von Lazarus?

Ich habe einfache Textdatei als Änderungsliste. Es Dauert ungefähr ca. 1/2 Stunde um LCL zu aktalisieren. LCL geht noch weil es automatisch kompiliert wird. Ich muss jetzt bei FCL einige Stellen ändern, das ist immer Handarbeit, erst make dann manuell kopieren.
Ich wollte eigentlich das meiste als Patch einrichen aber das interessiert keinen glaube ich.
Eigentlich gibt es sehr sinnvolle Sachen dabei. z.B. Ich habe TPopupNotifier zu "Ballonhilfe" erweitert.
Mit :

Code: Alles auswählen

 
MessageDlgPopup('Test','Hello',mtInformation);
 

hat man an eine Ecke seines Programmes kurze Infos auch mit Standard-Sound ausgeben. Mann muß nicht immer mit MessageDlg-Programmablauf anhalten.

Oder bei DBNavigator werden in Bearbeitungsmodus alle Knöpfe außer Abbrechen und Übernehmen automatisch deaktiert. Das habe ich gemacht, weil viele Benutzer immer fragten "Was soll ich jetzt drücken, Plus, Minus, Pfreil nach rechts, links..?".

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von Soner »

wp_xyz hat geschrieben:Das sind doch alles sehr sinnvolle Änderungen. Warum schreibst du nicht einen BugReport dafür? Wenn deine Wünsche ins Produkt einfließen, haben alle etwas davon und du musst dich nicht mehr um deine eigene Aktualisierung kümmern. Das ist das allerschönste an OpenSource!

Zu dem angeblichen Performance-Problem: Wenn es in deinem Programm zu einem Speicherengpass kommt, weil ein Bild kurzfristig zweimal im Speicher verhanden ist, hast du eh schon verloren.

Ich habe auch vor Patch zu reichen, aber das ist viel Arbeit. Ich bin bißchen Faul. Ich habe vor im original Forum eine Auflisting von Änderungen zu posten und zu fragen, welche davon die haben wollen. Nichst ist schlimmer als unnötige Arbeit.

Ich glaube du hast das Problem mit Performance nicht verstanden. Es hat nicht nur mit Speicher auch mit der Zeit zu tun.
Stelle dir vor wir beide bekommen einen Auftrag ein Programm zu schreiben, das soll aus einem Ordner mit über 1000 Bildern, die Bilder lesen und als Thumbnail darstellen. Du hättest auch mit einem PC mit 32GB RAM und neuste I7 verloren, weil dein Programm für laden und anzeigen immer mindestens doppelt Zeit beansprucht.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von Mathias »

Oder bei DBNavigator werden in Bearbeitungsmodus alle Knöpfe außer Abbrechen und Übernehmen automatisch deaktiert. Das habe ich gemacht, weil viele Benutzer immer fragten "Was soll ich jetzt drücken, Plus, Minus, Pfreil nach rechts, links..?".

Und einfach eine Komponente zu vererben, dies führt auch vielfach zum Ziel. Ich musste bis jetzt nichts an der LCL rumbasteln.
Verbesserungen kann man im Bugreport vorschlagen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von wp_xyz »

Soner hat geschrieben:
wp_xyz hat geschrieben:Ich glaube du hast das Problem mit Performance nicht verstanden. Es hat nicht nur mit Speicher auch mit der Zeit zu tun.
Stelle dir vor wir beide bekommen einen Auftrag ein Programm zu schreiben, das soll aus einem Ordner mit über 1000 Bildern, die Bilder lesen und als Thumbnail darstellen. Du hättest auch mit einem PC mit 32GB RAM und neuste I7 verloren, weil dein Programm für laden und anzeigen immer mindestens doppelt Zeit beansprucht.

Richtig, ich hab's nicht verstanden. Diese Betrachtung ist quantitiv nicht richtig, weil das Programm mehr zu tun hat als die Bilder unnötigerweise ins Picture zu kopieren (warum das in diesem speziellen Fall überhaupt?). Plattenzugriff für Lesen und Schreiben und Umskalieren der Bitmaps schlagen viel mehr zu Buche, und ich möchte fest wetten, dass kein Unterschied feststellbar ist.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von mse »

Soner hat geschrieben:Ich habe einfache Textdatei als Änderungsliste. Es Dauert ungefähr ca. 1/2 Stunde um LCL zu aktalisieren. LCL geht noch weil es automatisch kompiliert wird. Ich muss jetzt bei FCL einige Stellen ändern, das ist immer Handarbeit, erst make dann manuell kopieren.

Warum benutzt du nicht eine eigene Branch in git? Git mirrors von FPC und Lazarus gibt es hier:
https://github.com/graemeg/lazarus
https://github.com/graemeg/freepascal
Ein bewährtes Werzeug zur Vereinfachung der Arbeit mit git ist hier:
https://sourceforge.net/projects/mseuniverse/

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von Soner »

mse hat geschrieben:Warum benutzt du nicht eine eigene Branch in git? Git mirrors von FPC und Lazarus gibt es hier:
https://github.com/graemeg/lazarus
https://github.com/graemeg/freepascal
Ein bewährtes Werzeug zur Vereinfachung der Arbeit mit git ist hier:
https://sourceforge.net/projects/mseuniverse/

Danke, Ich werde mir das angucken.


wp_xyz hat geschrieben:Richtig, ich hab's nicht verstanden. Diese Betrachtung ist quantitiv nicht richtig, weil das Programm mehr zu tun hat als die Bilder unnötigerweise ins Picture zu kopieren (warum das in diesem speziellen Fall überhaupt?). Plattenzugriff für Lesen und Schreiben und Umskalieren der Bitmaps schlagen viel mehr zu Buche, und ich möchte fest wetten, dass kein Unterschied feststellbar ist.

Das war grobes Beispiel und TPicture wird meistens als universelles Austauschobjekt zwischen Grafikbibliotheken verwendet.
Wenn du meinst das ca 8 MB(1920x1080x4) große Datei 2000 mal zu erzeugen, kopieren freigeben gleich schnell wie 1000 mal ist, dann weiß ich nicht mehr.
Das ganze erinnert mich langsam an die Diskussion von vor einigen Jahren, da hatte jemand gesagt, bei 50-60 GB große Exe-Dateien spiele Dateigröße keine Rolle, weil die Festplattenkontroller das automatisch in den Speicher laden.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von wp_xyz »

Soner hat geschrieben:Das war grobes Beispiel und TPicture wird meistens als universelles Austauschobjekt zwischen Grafikbibliotheken verwendet.
Wenn du meinst das ca 8 MB(1920x1080x4) große Datei 2000 mal zu erzeugen, kopieren freigeben gleich schnell wie 1000 mal ist, dann weiß ich nicht mehr.
Das ganze erinnert mich langsam an die Diskussion von vor einigen Jahren, da hatte jemand gesagt, bei 50-60 GB große Exe-Dateien spiele Dateigröße keine Rolle, weil die Festplattenkontroller das automatisch in den Speicher laden.

Oh Mann, du drehst einem aber wirklich das Wort im Munde um!

Abgesehen davon, dass bisher noch nie von 8MB großen Bildern die Rede war, habe ich nie abgestritten, dass die Bearbeitung von so großen Bildern seine Zeit dauert (und dabei sind die 8 MegaPixel-Bilder ja noch gar nicht groß). Es ging darum, dass du behauptet hast, das unnötige Umkopieren eines Bildes würde doppelt solange dauern also ohne.

Schau dir die beigefügte Demo an. Der obere Button erzeugt als Arbeitsmaterial 20 Bitmaps mit zufälligem Inhalt, jeweils 1920x1080 - dauert bei mir 1.5 sec. Der mittlere Button erzeugt zu jedem Bild ein linear 10x kleineres Thumbnail, bei mir in 6.6 sec, und zwar auf dem direkten Weg. Der untere Button erzeugt zusätzlich noch ein TPicture und kopiert des eingelesene Bitmap dort hinein - dauert genauso lang!

Ich will damit nur ausdrücken, dass solche "Optimierungen" wie du weiter oben vorgeschlagen hast, oft gar nicht so viel bringen, zumindest nicht für "Wald-und-Wiesen-Aufgaben" - ich will aber nicht abstreiten, dass es Anwendungsfälle geben könnte, wo der Unterschied deutlicher ausfällt, aber dann kann man an anderer Stelle wahrscheinlich mehr gewinnen.
Dateianhänge
CreateThumbnails.zip
(2.66 KiB) 56-mal heruntergeladen

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: [ERLEDIGT]Wie kann man ein Bild übernehmen ohne zu kopie

Beitrag von Soner »

Ich habe es übertrieben/überspitzt gesagt, natürlich fällt das bei kleinen Bildern nicht auf.
Aber wenn überall sollche kleine Leistungsersparnisse verschwendet werden, dann kommt es am Ende etwas zusammen.
Ich mag es nicht wenn etwas verschwendet wird, wenn ich es vermeiden kann dann nutze ich es, deshalb habe ich es für mich gemacht.

Ich habe auch test gemacht:

Code: Alles auswählen

 
procedure TForm1.BtnTest1Click(Sender: TObject);
var t1, t2,t3: QWord;
    i,w, h: Integer;
    pic: TPicture;
    bmp: TBitmap;
begin
  pic:=TPicture.Create;
 try
  w:=7680; h:=4320;
  //w:=1920; h:=1080;
 
    t1:=GetTickCount64;
  for i:=1 to SpinEdit1.Value do begin;
    bmp := TBitmap.Create;
    bmp.SetSize(w, h);
    bmp.Canvas.FillRect(10,10,20,30);
    pic.Graphic:=bmp;
    bmp.Free;
    TBitmap(pic.Graphic).Canvas.FillRect(50,50,60,60);;
  end;
 
  t2:=GetTickCount64;
  for i:=1 to SpinEdit1.Value do begin;
    bmp := TBitmap.Create;
    bmp.SetSize(w, h);
    bmp.Canvas.FillRect(10,10,20,30);
    pic.SetGraphicDirect(bmp);
    //bmp Nicht freigeben, es gehört jetzt zu pic: bmp.Free;
    TBitmap(pic.Graphic).Canvas.FillRect(50,50,60,60);;
  end;
  t3:=GetTickCount64;
  Memo1.Lines.Add('Vergleich1 ----- ');
  Memo1.Lines.Add('SetGraphic in ms: '+IntToStr(t2-t1));
  Memo1.Lines.Add('SetGraphicDirect in ms: '+IntToStr(t3-t2));
 
 
 finally
   pic.Free;
 end;
end;
 
procedure TForm1.BtnTest2Click(Sender: TObject);
var t1, t2, z1,z2: QWord;
    i, w, h: Integer;
    pic: TPicture;
    bmp: TBitmap;
begin
  pic:=TPicture.Create;
 try
   z1:=0; z2:=0;
   //w:=7680; h:=4320;
   w:=3840; h:=2160;
   //w:=1920; h:=1080;
  for i:=1 to SpinEdit1.Value do begin;
    bmp := TBitmap.Create;
    bmp.SetSize(w, h);
    bmp.Canvas.FillRect(10,10,20,30);
    t1:=GetTickCount64;
    pic.Graphic:=bmp;
    t2:=GetTickCount64;
    z1:=z1+(t2-t1);
    bmp.Free;
    TBitmap(pic.Graphic).Canvas.FillRect(50,50,60,60);;
  end;
 
 
  for i:=1 to SpinEdit1.Value do begin;
    bmp := TBitmap.Create;
    bmp.SetSize(w, h);
    bmp.Canvas.FillRect(10,10,20,30);
    t1:=GetTickCount64;
    pic.SetGraphicDirect(bmp);
    t2:=GetTickCount64;
    z2:=z2+(t2-t1);
    //bmp Nicht freigeben, es gehört jetzt zu pic: bmp.Free;
    TBitmap(pic.Graphic).Canvas.FillRect(50,50,60,60);;
  end;
 
  Memo1.Lines.Add('Direktvergleich ----- ');
  Memo1.Lines.Add('SetGraphic in ms: '+IntToStr(z1));
  Memo1.Lines.Add('SetGraphicDirect in ms: '+IntToStr(z2));
 
 finally
   pic.Free;
 end;
 
end;
 


Ergebnisse vom ersten Test ist das gleiche wie deine Ergebnisse:

Code: Alles auswählen

 
Vergleiche-Button 5x geklickt.
 
Vergleich1(ganze Schleife gemessen) ---- 7680x4320
Vergleich1 -----
SetGraphic in ms: 3011
SetGraphicDirect in ms: 2620
Vergleich1 -----
SetGraphic in ms: 2979
SetGraphicDirect in ms: 2606
Vergleich1 -----
SetGraphic in ms: 2980
SetGraphicDirect in ms: 2605
 
Vergleich1(ganze Schleife gemessen) ---- 1920x1080
SetGraphic in ms: 171
SetGraphicDirect in ms: 156
Vergleich1 -----
SetGraphic in ms: 172
SetGraphicDirect in ms: 156
Vergleich1 -----
SetGraphic in ms: 172
SetGraphicDirect in ms: 156
Vergleich1 -----
SetGraphic in ms: 172
SetGraphicDirect in ms: 140
Vergleich1 -----
SetGraphic in ms: 172
SetGraphicDirect in ms: 156
 



Im zweiten Test wird nur die Zeit, die verschwendet wird gemessen, für kleine Bilder nicht richtig meßbar, aber für große Bilder sieht man den unterschied deutlich. Natürlich kann man auch sagen "Wer verwendet schon 7680x4320 Bilder?" oder "Das sind doch Milisekunden Unterschiede.", dann wären wir am Anfang.

Code: Alles auswählen

 
Direktvergleich (nur Grafikzuweisungsteile) ----- 7680x4320
SetGraphic in ms: 606
SetGraphicDirect in ms: 158
Direktvergleich -----
SetGraphic in ms: 622
SetGraphicDirect in ms: 171
Direktvergleich -----
SetGraphic in ms: 627
SetGraphicDirect in ms: 155
Direktvergleich -----
SetGraphic in ms: 640
SetGraphicDirect in ms: 188
Direktvergleich -----
SetGraphic in ms: 621
SetGraphicDirect in ms: 172
 
 
Direktvergleich (nur Grafikzuweisungsteile) ----- 3840x2160
SetGraphic in ms: 110
SetGraphicDirect in ms: 96
Direktvergleich -----
SetGraphic in ms: 110
SetGraphicDirect in ms: 47
Direktvergleich -----
SetGraphic in ms: 78
SetGraphicDirect in ms: 16
Direktvergleich -----
SetGraphic in ms: 125
SetGraphicDirect in ms: 31
Direktvergleich -----
SetGraphic in ms: 95
SetGraphicDirect in ms: 63
 
 
 
Nicht richtig messbar.
Direktvergleich ----- (nur Grafikzuweisungsteile) ----- 1920x1080
SetGraphic in ms: 0
SetGraphicDirect in ms: 0
Direktvergleich -----
SetGraphic in ms: 32
SetGraphicDirect in ms: 0
Direktvergleich -----
SetGraphic in ms: 46
SetGraphicDirect in ms: 47
Direktvergleich -----
SetGraphic in ms: 15
SetGraphicDirect in ms: 0
 


EDIT: Die nächsten ursprunglichen Aussagen von mir sind falsch. Jetzt erinnere ich mich wieder, ich hatte vergessen für fpc Assemblerroutinen einzuschalten, danach konnte man keinen Unterschied festellen.
Solche Milisekundenunterschiede sieht man später im Programm. Ich wollte vor Jahren mein einfaches Grafikviewer von TurboDelphi zu Lazarus portieren, obwohl Graphics32-Bibliothek für beide Paltformen gleichen Code verwendet lief die Delphiversion flüssiger. Sobald man 1920x1080 auf 200% vergrößerte war verschieben des Bildabschnitts bei Lazarusversion langsamer.

Antworten