Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 附加阵列缓冲器_Javascript_Arraybuffer_Typed Arrays - Fatal编程技术网

Javascript 附加阵列缓冲器

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

附加/组合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的长度是固定的,您无法避免创建新的缓冲区,但是有必要初始化类型化数组吗?到达后,我只希望能够将缓冲区视为缓冲区;类型和结构无关紧要。

您始终可以使用
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,我可以。尽管现在,我不推荐最后一个选项——它可能会变得太大,使浏览器中的选项卡崩溃,甚至可能导致节点溢出(猜测)