32

附加/组合 ArrayBuffers 的最佳方式是什么?

我正在接收和解析具有各种数据结构的网络数据包。传入的消息被读入 ArrayBuffers。如果部分数据包到达,我需要存储它并等待下一条消息,然后再重新尝试解析它。

目前我正在做这样的事情:

function appendBuffer( buffer1, buffer2 ) {
  var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength );
  tmp.set( new Uint8Array( buffer1 ), 0 );
  tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
  return tmp.buffer;
}

显然,由于 ArrayBuffers 的长度是固定的,因此您无法避免必须创建一个新缓冲区,但是是否有必要初始化类型化数组?到达后,我只想能够将缓冲区视为缓冲区;类型和结构无关紧要。

4

4 回答 4

7

为什么不使用 Blob ?(我意识到当时它可能不可用)。

只需使用您的数据创建一个 Blob,var blob = new Blob([array1,array2,string,...])然后使用 FileReader 将其转换回 ArrayBuffer(如果需要)(请参阅this)。

检查一下:BlobBuilder 和新的 Blob 构造函数有什么区别? 还有这个:MDN Blob API

编辑 :

我想比较这两种方法(Blob,以及问题中使用的方法)的效率并创建了一个 JSPerf:http: //jsperf.com/appending-arraybuffers

好像使用 Blob 比较慢(其实我猜是使用 Filereader 读取 Blob 最耗时)。所以现在你知道了 ;) 当有超过 2 个 ArrayBuffer 时(比如从块中重建文件),也许我会更有效率。

于 2014-07-03T09:30:00.493 回答
1

您似乎已经得出结论,无法创建新的数组缓冲区。但是,出于性能考虑,将缓冲区的内容附加到标准数组对象,然后从中创建新的数组缓冲区或类型化数组可能会有所帮助。

var data = [];

function receive_buffer(buffer) {
    var i, len = data.length;

    for(i = 0; i < buffer.length; i++)
        data[len + i] = buffer[i];

    if( buffer_stream_done()) 
        callback( new Uint8Array(data));
}

大多数 javascript 引擎已经为动态分配的内存留出了一些空间。这种方法将利用该空间而不是创建大量新的内存分配,这可能是操作系统内核中的性能杀手。最重要的是,您还将减少一些函数调用。

第二个更复杂的选择是预先分配内存。如果您知道任何数据流的最大大小,那么您可以创建一个该大小的数组缓冲区,填充它(如果需要,部分填充),然后在完成后清空它。

最后,如果性能是您的主要目标,并且您知道最大数据包大小(而不是整个流),那么从少数几个该大小的数组缓冲区开始。当你填满你预先分配的内存时,在网络调用之间创建新的缓冲区——如果可能的话,异步的。

于 2017-10-16T10:52:42.733 回答
0
function concat (views: ArrayBufferView[]) {
    let length = 0
    for (const v of views)
        length += v.byteLength
        
    let buf = new Uint8Array(length)
    let offset = 0
    for (const v of views) {
        const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength)
        buf.set(uint8view, offset)
        offset += uint8view.byteLength
    }
    
    return buf
}
于 2021-11-17T13:23:38.593 回答
-3

您始终可以使用DataViewhttp://www.khronos.org/registry/typedarray/specs/latest/#8)而不是特定类型的数组,但正如您在问题的评论中提到的那样,您实际上不能自己做很多事情ArrayBuffer

于 2013-02-11T18:59:43.320 回答