c# - Performance tips mapping indexers to objects -


given following code able access pixels of image , map them color struct.

to eye though looks inefficient since every time access indexer reading array 4 times. takes 9 seconds on computer run.

what looking example of how optimise code. i'm guessing can sort of reference array using unsafe code , read in 1 move have yet find decent guide explain how , how apply approach other situations.

while code example on own aid me, explanation of going on , why improve performance more beneficial myself , reading.

public class program {     public static void main(string[] args)     {         image img = new image(10000,10000);          stopwatch stopwatch = new stopwatch();         stopwatch.start();                (int y = 0; y < img.height; y++)         {             (int x = 0; x < img.width; x++)             {                 color color = img[x,y];             }         }          stopwatch.stop();          console.writeline(         string.format("time: {0} ms", stopwatch.elapsedmilliseconds));          console.readkey();     } }  // define other methods , classes here public class image {      private float[] pixels;      public image (int width, int height){          pixels = new float[width * height * 4];         this.width = width;         this.height = height;            }     public int width { get; private set; }     public int height { get; private set; }      public color this[int x, int y]    {               {             int start = ((y * this.width) + x) * 4;            return new color(this.pixels[start],                              this.pixels[start + 1],                              this.pixels[start + 2],                              this.pixels[start + 3]);        }         set        {            int start = ((y * this.width) + x) * 4;             this.pixels[start] = value.r;            this.pixels[start + 1] = value.g;            this.pixels[start + 2] = value.b;            this.pixels[start + 3] = value.a;        }    }  }  public struct color {      public color (float r, float g, float b, float a):this(){         this.r = r;         this.g = g;         this.b = b;         this.a = a;     }      public float r {get;set;}      public float g {get;set;}      public float b {get;set;}      public float {get;set;} } 

update

so investigation i've been able perform improvements using unsafe code.

here's 1 approach indexer:

public unsafe class image {      private byte* pixels;      public image (int width, int height){          fixed(byte* p = &(new byte[width * height * 4])[0]){             this.pixels = p;         }          this.width = width;         this.height = height;     }     public int width { get; private set; }     public int height { get; private set; }     public color this[int x, int y]    {        { return *((color*)(this.pixels + ((y * this.width) + x) * 4)); }         set {                 color* c = (color*)(this.pixels + (((y * this.width) + x) * 4));                     c->r = value.r;                     c->g = value.g;                     c->b = value.b;                     c->a = value.a;             }    } } 

this around 50% faster concerned happens pixelsproperty. ever cleaned garbage collector? should image implementing idisposableso can set value null?

here's second approach:

public unsafe class image {      private byte[] pixels;      public image (int width, int height){          pixels = new byte[width * height * 4];         this.width = width;         this.height = height;            }     public int width { get; private set; }     public int height { get; private set; }            public color this[int x, int y]    {               {             fixed(byte* p = &this.pixels[0]){                 return *((color*)(p + ((y * this.width) + x) * 4));             }        }         set        {             fixed(byte* p = &this.pixels[0]){                 color* c = (color*)(p + (((y * this.width) + x) * 4));                 c->r = value.r;                 c->g = value.g;                 c->b = value.b;                 c->a = value.a;             }        }    } } 

this 28% faster , far can determine means not have further manage memory.

are there obvious flaws in either approach?

you're working exclusively 32-bit pixels. why use byte[] @ all, when can use uint[] instead, , use color.fromargb?

buffer.blockcopy can used efficiently copy between byte[] , uint[] (and other value type afaict), if you're reading file, that's 1 option. using unsafe code another. in both cases, pay lot of attention bounds checking - you're losing lot of memory safety guarantees.

if you're going bare-bones speed, you're going need lot of unsafe code. that's tricky, make sure need speed - profiling application whole idea.


Comments

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

reactjs - React router and this.props.children - how to pass state to this.props.children -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -