performance - How do I use a typed array using a shared buffer efficiently in JavaScript? -


in code have object contains series of pixel coordinates. performance of object critical because it's being used in 60fps game output cannot cached.

after experimentation , benchmarking, 3d array proved fastest way of implementing when using untyped arrays:

var pixelcollection = function() {     this.pixels = []; };  pixelcollection.prototype = {     add: function(x, y) {         var pixels = this.pixels;         if (pixels[y]) {             pixels[y].push(x);         } else {             pixels[y] = [x];         }     },     each: function(callback) {         var pixels = this.pixels;         (var y = 0, m = pixels.length; y < m; y++) {             var row = pixels[y];             if (row) {                 (var = 0, mm = row.length; < mm; i++) {                     callback(row[i], y);                 }             }         }     } }; 

in situations, object not fast enough, tried uint8array implementation, using 2d array:

var width = 255; var height = 160;  pixelcollection = function() {     this.pixels = new uint8array(width * height); };  pixelcollection.prototype = {     add: function(x, y) {         this.pixels[width * y + x] = 1;     },     each: function(callback) {         var pixels = this.pixels;         (var = 0, m = pixels.length; < m; i++) {             if (pixels[i]) {                 callback(i % width, math.floor(i / width));             }         }     } } 

this slower. thought faster because writing - , reading uint8arrays faster, since i'm creating huge object every pixelcollection object, retrieving pixels way slower because takes longer iterate on pixels. (note: tried implementation above untyped array: lot slower)

a pixelcollection typically not have pixels set. however, bounding box may span entire canvas need create array using buffer big.

there may way around though. can create 1 big shared buffer , use byte offset every pixelcollection. when pixelcollection p1 take 100 bytes, pixelcollection p2 start @ byte offset 100. uses memory more efficiently, need keep track of range of bytes every pixelcollection uses (is c calls "pointers"?).

annoying part: when p1's bounding box expands, need shift p2 make space p1. , need set safe buffer size shared buffer, need make safe guesstimation of how memory needs.

implementing possible, require lots of time, trial , error.

so before start on this: seem way it? there better or simpler ways this? know example implementations learn from?

edit: i added jsperf in case want try hand @ optimization.
please add jsperf if have brilliant idea optimization.

by slower guess mean running pixelcollection.each? second example might slower if there aren't many points set 1, still checks possible locations whilst first runs through added points. if want every possible nanosecond @ cost (in case memory), can pre-allocate maximum size in 2 uint8arrays , separately keep track of size.

var width = 255; var height = 160;  var pixelcollection = function() {     this.pixels.length = 0;     this.pixels.x = new uint8array(width * height);     this.pixels.y = new uint8array(width * height);  };  pixelcollection.prototype = {     add: function(x, y) {         this.pixels.x[this.pixels.length] = x;         this.pixels.y[this.pixels.length] = y;         this.pixels.length++;     },     each: function(callback) {         var pixels = this.pixels;         (var = 0; < this.pixels.length; i++) {             callback(this.pixels.x[i], this.pixels.y[i]);          }     } }; 

if know limit number of additions pixelcollection have can reduce memory usage. combine 2 arrays 1 double length alternating x , y values.

however, if want able remove individual points method gets tricky, it's unlikely faster first method @pudge601's loop change.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -