Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Bitmap: Pixels[i,j] gegen Scanline
GuaAck - Fr 05.12.14 21:38
Titel: Bitmap: Pixels[i,j] gegen Scanline
Hallo,
als Nachtrag zu meiner Frage unten:
Mit meinem Programm war mal Pixels[i,j] schneller und mal Scanline. In der Delphi-Hilfes steht, dass Scanline nur für Device-independent-Bitmaps (DIB) angewendet werde.
Da habe ich einen kleinen Test gemacht und eine frisch creierte Bitmap zeilenweise mit Pixelfarbe beschrieben (Aus Zeile und Spalte, so dass ein hübsches, erkennbares Muster entsteht)
Die Tabelle unten zeigt: Scanline ist schnell, aber nur bei DIBs (pF24bit und pf32bit gelten nach Delphi-Hilfe als DIBs). pfdevice ist Default bei TBitmap.create!
Für die, die experimentieren wollen, Quellcode im Anhang.
Für 2000 x 1500 Bitmap:
pfdevice: Pixels[]: 3,829 s
pfdevice: Scanline: 14,953 s
pf24bit : Pixels[]: 1,859 s
pf24bit : Scanline: 0,016 s
pf32bit : Pixels[]: 1,875 s
pf32bit : Scanline: 0,016 s
Gruß
GuaAck
Horst_H - Fr 05.12.14 22:07
Hallo,
Mit32 Bit Lazarus/FPc 1.26/2.6.4: (Haswell i3-4330 3.5 Ghz auf Linux 3.17.4 )
Da ist wohl pfdevice anders gelöst, aber sonst sehr ähnlcih.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| Bitte auf Fertig warten pfdevice: Pixels[]: 1.698 s pfdevice: Scanline: 0.013 s pf24bit : Pixels[]: 1.784 s pf24bit: Scanline: 0.014 s pf32bit : Pixels[]: 1.988 s pf32bit: Scanline: 0.014 s Fertig. |
Gruß Horst
SMO - So 07.12.14 21:53
GuaAck hat folgendes geschrieben : |
Mit meinem Programm war mal Pixels[i,j] schneller und mal Scanline. In der Delphi-Hilfes steht, dass Scanline nur für Device-independent-Bitmaps (DIB) angewendet werde.
Da habe ich einen kleinen Test gemacht und eine frisch creierte Bitmap zeilenweise mit Pixelfarbe beschrieben (Aus Zeile und Spalte, so dass ein hübsches, erkennbares Muster entsteht)
Die Tabelle unten zeigt: Scanline ist schnell, aber nur bei DIBs (pF24bit und pf32bit gelten nach Delphi-Hilfe als DIBs). pfdevice ist Default bei TBitmap.create! |
Scanline ist eigentlich
immer schneller!
Ja, du kannst Scanline bei pfDevice verwenden, aber das ist ganz schlechter Stil, denn im Hintergrund passiert das:
1. TBitmap.GetScanLine wird aufgerufen
2. Das ruft TBitmap.Changing auf
3. Das wiederum ruft TBitmap.FreeImage auf, welches ein eventuell vorhandenes DIBHandle freigibt, wenn das Bitmap ein DDB (pfDevice) ist.
4. Jetzt sind wir zurück in TBitmap.GetScanLine, was logischerweise ein DIB benötigt um direkt auf die Pixeldaten zugreifen zu können.
Also ruft es TBitmap.DIBNeeded auf, was das DDB in ein DIBHandle kopiert.
Es ist also so, dass bei pfDevice
jede Benutzung von Scanline ein neues, temporäres DIB erstellen muss, wobei die Pixeldaten dann hin- und her kopiert werden! Kein Wunder also, dass das bei größeren Dimensionen langsamer wird.
GuaAck - So 07.12.14 22:55
Hallo SMO,
vielen Dank für Deine umfassende Erklärung. Ich hatte mir im CPU-Fenster schon mal angesehen, was so etwa passiert. Da fiel mir auf, das jedesmal DIBneeded aufgerufen wurde, und ich ahnte, dass der Ablauf umständlich sein könnte, passt ja bestens zu Deiner Erklärung.
Gruß
GuaAck
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!