Zurück zu Pi7.eu
BLOG
C++ Performance
Das kostet Rechenzeit:
- Funktionsaufruf
- Übergabe jedes einzelnen Funktion Parameters
- Nicht referenzierte Parameter kosten noch viel mehr Rechenzeit (muss in einen neuen Speicherbereich kopiert werden)

Das weniger Rechenzeit:
- Vergleiche von Variablen gleicher Bit-Größe brauchen immer gleich viel Rechenzeit (egal ob Byte==Byte oder LDWORD==LDWORD) da die meisten Compiler und Prozessoren dafür bis zu 128 Bit Optimiert sind
Zum Beispiel: will man eine Farbe mit einer anderen vergleichen:
C++
// So nicht! BYTE c1[4] = { 0, 0, 0, 0 }; BYTE c2[4] = { /* ..? */ }; if( c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2] && c1[3] == c2[3] ) { // ... } // So richtig! DWORD c1 = 0x00000000; DWORD c2 = /* ..? */; if( c1 == c2 ) { // ... } // Nachteile das lesen und schreiben einzelner werte benötigt mehr Zeit!


Arbeiten mit Bildern / Screenshots etc.

Durchlaufen des Pixel-Arrays:
Optimaler weise:
Ist das Pixel-Array 1-Dimensional, also eine Folge aller Pixel (Zeilen hintereinander).
Ein Pixel 32 Bits groß, also repräsentativ für 4 mal 1 Byte von jeweils Rot, Grün, Blau und (Nichts oder Alphawert).
Suche nach einem bestimmten Farbwert:
C++
// TODO: int width = Breite des Bildes // TODO: int height = Höhe des Bildes // TODO: DWORD* picRGBA = Mein Pixel-Array der Länge width * height // TODO: DWORD color = Meine gesuchte Farbe (Zum Beispiel 0xFFFFFF00 für undurchsichtiges Weiß) // Anzahl Pixel FullHD: 2.073.600 - int bis 2.147.483.647 -> reicht locker! (Tausendfach) int min = 0; int max = width * height; for( int pix = min; pix < max; ++pix ) { if( picRGBA[pix] == color ) { int y = pix / width; // Ganzahldivision benötigt!!! int x = pix - y; // Verarbeitung des gefundenen Pixel } }

Erläuterung:
Nehmen wir an wir haben ein FullHD-Bild mit 2.073.600 Pixeln, also width = 1920; und height = 1080;
Die for-Schleife muss also 2.073.600 durchlaufen werden. Was im günstigsten Fall bedeutet, dass:
1. geprüft wird ob pix schon maximal ist
2. das Color-DWORD aus dem Array geholt wird und mit der Farbe Verglichen wird
3. pix um 1 erhöht
Das sind sehr wenige Schritte!
Im schlimmsten Fall wurde die richtige Farbe gefunden und das x und y müssen, falls benötigt, berechnet werden. D
TIPP: max wird vor der for-Schleife berechnet, da sonst width * height jedes mal neu berechnet wird! (Der kompiler geht in den meisten Fällen davon aus, dass sich diese Variablen innerhalb der Schleife noch ändern könnten, was natürlich eine Neuberechnung verlangt)

Vorteile:
Minimaler Aufwand (Rechenzeit)

Nachteile:
Einzelne Farbkanäle nicht prüfbar (Würde pro Farbkanal mindestens einen weiteren Schritt benötigen)
Bei häufigem Auftreten von Color langsamer als eine Verschachtelte for-Schleife mit x und y

Sollte man nur das erste Vorkommen des Pixel suchen, kann man den Script noch etwas optimieren:
C++
// TODO: Variablen sind wie im vorherigen Code vorbelegt int size = width*height; // ACHTUNG: das picRGBA muss am Ende ein Pixel mehr enthalten als nötig! picRGBA[ size ] = color; int pix = 0; while( picRGBA[pix++] != color ); if( pix < size ) { int y = pix / width; // Ganzahldivision benötigt!!! int x = pix - y; // Verarbeitung des gefundenen Pixel }

Hierbei spart man sich den Vergleich mit max.


C++
void findPixel( DWORD* picRGBA, int width, int height, DWORD Color, void (*callback) (int x, int y) ) { // Anzahl Pixel FullHD: 2.073.600 - int bis 2.147.483.647 -> reicht locker! (Tausendfach) int min = 0; int max = width * height; for( int pix = min; pix < max; ++pix ) { if( picRGBA[pix] == color ) { int y = pix / width; // Ganzahldivision benötigt!!! int x = pix - y; callback( x, y ); // Verarbeitung des gefundenen Pixel } } }
Autor: Pierre
erstellt am 17.07.2013 14:27 - aktualisiert am 18.07.2013 13:01
590 Aufrufe
...
You can share this Blog on Facebook, Google+ and Twitter! ... what about Skype?
Johans

23.07.2013 12:11
TOP :super:
Pascal

13.09.2013 16:16
?:verwirrt: