Feedback

C# - Leistung inkrementieren; For-For Schleifen

Veröffentlicht von am 11/4/2015
(0 Bewertungen)
Guten Tag,
ich war durch ein Video(https://www.youtube.com/watch?v=B4DuT61lIPU) aufmerksam gemacht worden, Code so weit optimieren zu können, dass die Leistung um (in meinem Beispiel) circa 16% inkrementiert werden kann.

Man denke, man habe ein Bild(2-Dimensional), und deklariert und initialisiert sie in einem 1-Dimensionalem Array(Merke: 1-Dimensionale Arrays sind expressis verbis schneller als 2-Dimensionale Arrays)

Will man nun über die Index-Formel x + y * WIDTH auf das Element k zugreifen(durch Iteration), so muss gelten, dass x als erstes iteriert wird.

Soll heißen, y + 1, wenn x == WIDTH und nicht x + 1 wenn y == HEIGHT.

Warum?

Wenn wir uns betrachten:
Wir iterieren y als erstes, dann gilt
(WIDTH exemplarisch 2048)
for x = 0 to width
for y = 0 to height
Index = x + y * WIDTH
(y = 1)
(x = 0)

Index = 0 + 1 * 2048 = 2048.

next
next

Das heißt, dass die üblichen 2047 Elemente geladen, aber nicht benutzt und verworfen werden(!).

Abhilfe schafft sequenzielles Iterieren:

for y = 0 to HEIGHT
for x = 0 to WIDTH
Index = x + y * WIDTH
Index = 1 + 0 * 2048 = 1
next
next

Index bei x = 1 ist 1(!).
Nur 1(!) Element wird geladen.

Ein Codebeispiel in C#


//‏بسم الله الرحمن الرحيم ‎

//developed by ~3r0rXx


public Color GetColor(Texture2D Texture) //XNA/MONOGAME 
{
Color[] __chace = new Color[Texture.Width * Texture.Height];
Color[] __copier = new Color[255 + 255 + (255 * 1)];
int[] __chace1 = new int[255 + 255 + (255 * 1)];
 
Func<byte, byte, byte, int, long> hash = (byte r__in, byte g__in, byte b__in, int n) =>
{
	var h = 0L;
	for (byte i = 0; i < 1; i++)
	{
		h = r__in + g__in + (b__in * i);
	}
	return h;
};

Texture.GetData<Color>(__chace);

      int __index = 0;
            int __max = __chace1[__index];
            for (int j = 0; j < Texture.Height; j++)
            {
                for (int i = 0; i < Texture.Width; i++)
                {
                    var c = __chace[i + j * Texture.Width];
                    var h = hash(c.R, c.G, c.B, Texture.Width * Texture.Height);
                    __chace1[h]++;
                    __copier[h] = c;
                    if (__chace1[h] > __max)
                    {
                        __max = __chace1[h];
                        __index = (int)h;
                    }
                }
            }

return __copier[__index];
}

//Ergebnis im Release Mode
//0.06 ms

//Dasselbe mit y-Erst-Iteration
//0.35 ms
Abgelegt unter Sequenziell, Optimierung.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!