Search code examples
javascriptarraysarraybuffertyped-arrays

Comparison: Resizing ArrayBuffer with buffer views (Uint8 vs Float64), am I missing something?


I've been looking up ways how to resize ArrayBuffers and I've come to the following two methods:

1 (Uint8Array):

function resizeUint8(baseArrayBuffer, newByteSize) {
    var resizedArrayBuffer = new ArrayBuffer(newByteSize),
        resizedView = new Uint8Array(resizedArrayBuffer),
        baseView = new Uint8Array(baseArrayBuffer);

    for(var i = 0; i < baseView.length; i++) {
        resizedView[i] = baseView[i];
    }

    return resizedArrayBuffer;
}

2 (Float64Array):

// newByteSize is divisible by 8
function resizeFloat64(baseArrayBuffer, newByteSize) {
    var resizedArrayBuffer = new ArrayBuffer(newByteSize),
        resizedView = new Float64Array(resizedArrayBuffer),
        baseView = new Float64Array(baseArrayBuffer);

    for(var i = 0; i < baseView.length; i++) {
        resizedView[i] = baseView[i];
    }

    return resizedArrayBuffer;
}

Comparison: #1 utilizes Uint8Arrays therefore for every byte in the baseArrayBuffer you have to individually copy it to the resized array buffer. Now for #2 I utilize a Float64Array, therefore I can iterate over 8x fewer indices to get the same result.

Concern: Using a Float64Array seems like the obvious "more performant" approach; however, is there something i'm missing when using a Float64Array? Do I lose value precision when setting each index via the Float64Array view? Is there any other drawbacks (other than ensuring the byte size is divisible by 8)?


Solution

  • Instead of copying every element in a for loop, use typedArray.set method, it's faster

    function resizeUint8(baseArrayBuffer, newByteSize) {
        var resizedArrayBuffer = new ArrayBuffer(newByteSize),
            len = baseArrayBuffer.byteLength,
            resizeLen = (len > newByteSize)? newByteSize : len;
    
            (new Uint8Array(resizedArrayBuffer, 0, resizeLen)).set(new Uint8Array(baseArrayBuffer, 0, resizeLen));
    
        return resizedArrayBuffer;
    }
    

    JSFiddle test: http://jsfiddle.net/92zsn529/