Javascript 附加阵列缓冲器
附加/组合ArrayBuffers的首选方法是什么 我正在接收和解析具有各种数据结构的网络数据包。传入消息被读入ArrayBuffers。如果部分数据包到达,我需要存储它并等待下一条消息,然后再尝试解析它 目前我正在做这样的事情:Javascript 附加阵列缓冲器,javascript,arraybuffer,typed-arrays,Javascript,Arraybuffer,Typed Arrays,附加/组合ArrayBuffers的首选方法是什么 我正在接收和解析具有各种数据结构的网络数据包。传入消息被读入ArrayBuffers。如果部分数据包到达,我需要存储它并等待下一条消息,然后再尝试解析它 目前我正在做这样的事情: function appendBuffer( buffer1, buffer2 ) { var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength ); tmp.set( new Uint
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的长度是固定的,您无法避免创建新的缓冲区,但是有必要初始化类型化数组吗?到达后,我只希望能够将缓冲区视为缓冲区;类型和结构无关紧要。您始终可以使用
DataView
()而不是特定的类型化数组,但正如您在问题的评论中所提到的,您实际上无法单独使用ArrayBuffer
。为什么不使用Blob?(我意识到当时可能没有)
只需使用数据创建一个Blob,如var Blob=newblob([array1,array2,string,…])
并使用文件读取器将其转换回ArrayBuffer(如果需要)(请参阅)
选中此项:
这是:
编辑:
我想比较这两种方法(blob和问题中使用的方法)的效率,并创建了一个JSPerf:
似乎使用Blob的速度较慢(事实上,我猜使用Filereader读取Blob花费的时间最多)。现在你知道了;)
如果有2个以上的ArrayBuffer(如从文件块重建文件),可能会更有效。您似乎已经得出结论,无法创建新的数组缓冲区。但是,出于性能考虑,将缓冲区的内容附加到标准数组对象,然后从该对象创建新的数组缓冲区或类型化数组可能是有益的
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));
}
var数据=[];
函数接收缓冲区(缓冲区){
变量i,len=data.length;
对于(i=0;i
大多数javascript引擎已经为动态分配的内存留出了一些空间。此方法将利用该空间,而不是创建大量新的内存分配,这可能是操作系统内核中的性能杀手。除此之外,您还将删除一些函数调用
第二个更复杂的选择是预先分配内存。
如果您知道任何数据流的最大大小,那么您可以创建一个该大小的数组缓冲区,填充它(必要时部分填充),然后在完成时清空它
最后,如果性能是您的主要目标,并且您知道最大数据包大小(而不是整个数据流),那么从少量该大小的数组缓冲区开始。在填充预先分配的内存时,在网络调用之间创建新的缓冲区——如果可能的话,异步创建 上述问题的解决方案提供了我目前的方法,即将类型化数组组合到一个新的缓冲区中。在处理类型化数组时,这很好。我想完全避开它们。我的问题是这是否可能。你只有
数组缓冲区的切片,没有多少办法。然后你有了.append
和BlobBuilder
,但这将比你已经在做的事情复杂得多。您当前的方法真的有问题吗?@Esailija我真正关心的是性能,尽管我还没有达到测试阶段。这似乎是一种反手的方式。还在习惯JS!谢谢。每个ArrayBuffer
都有固定的大小,所以复制数据是唯一的方法。您希望使用本机代码来执行复制,而不是Javascript循环,因此Uint8Array.set
是您的最佳选择-它可以检测其参数何时是另一个Uint8Array
,并执行高速C风格的memcpy
。因此,您的原始代码示例非常快速和简单,ArrayBuffer
类没有有用的方法,因为它的设计者希望类型化数组是主要接口。因此,我更喜欢使用Uint8Array
表示“原始数据”,不是ArrayBuffer
。在这方面,它怎么会比Uint8数组更好呢?@BHSPitMonkey它不是真的-提到它的唯一原因是它没有假定特定的元素类型。如果只是为了复制数据,那么将所有内容都视为Uint8没有什么错,这里就是这种情况。如果您需要DataView所提供的灵活性,那么DataView是非常好的,但是它的性能要差得多。请参阅:但这是异步的……事实上,尽管如此,我仍然觉得它更容易使用。@Bergi如果在中使用它,您可以使用。@JbDrucker您知道如何以及何时为blob释放内存吗?Blob.close()现在看起来像是我的测试版(64位,Windows 10,Intel Core i7),你测试的第4版说在Firefox 56中使用Blob的速度是2倍,在Chrome 61中使用appendBuffer的速度是6倍。我希望看到这方面的一些基准。如果我能学会使用JSperf XD,我可以。尽管现在,我不推荐最后一个选项——它可能会变得太大,使浏览器中的选项卡崩溃,甚至可能导致节点溢出(猜测)