Search code examples
javascriptv8typed-arrays

Fastest way to fill Uint16Array with a single value


var a = Uint16Array(16384), n = a.length, c = 65;
for (var i = 0; i < n; i++) a[i] = c;

Is there a way to do this faster? This is a typed array of two-byte per cell.

I recall memset() from C or fillchar from Pascal.


Solution

  • In theory, the new fill() method on typed arrays would be a natural candidate as it would fill the buffer internally at compiled speed, and therefor performance faster.

    Unfortunately, this isn't the case. This performance test show that, at the time of writing this, a traditional while-loop is many times faster. Even when this test has a slight penalty for the while-loop.

    In addition, fill() is only supported in Firefox at the moment.

    snap

    So the fastest method using an Uint16Array only, and with best cross-platform support is doing:

    var i = 0, a = new Uint16Array(16384);
    while(i < 16384) a[i++] = 65;
    

    Uint16/32 arrays are always memory aligned, so you could in some cases where the length of them match up on a four byte boundary, fill using a 32-bit array instead with a 2x16 bit value (refactor at will):

    var i = 0, len = 16384, a = new Uint16Array(len), c = 65;
    if (len % 4) {
        while(i < len) a[i++] = c;            // fill Uint16Array as-is
    }
    else {
        var u32 = new Uint32Array(a.buffer),  // shares the same byte-buffer as a
            len32 = u32.length,
            v = (c << 16) | c;                // make value span 2x16 bits
        while(i < len32) u32[i++] = v;        // fill at close to 2x speed
    }
    // use "a" here