Javascript 附加 ArrayBuffers
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10786128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Appending ArrayBuffers
提问by user1421750
What is the preferable way of appending/combining ArrayBuffers?
附加/组合 ArrayBuffers 的首选方法是什么?
I'm receiving and parsing network packets with a variety of data structures. Incoming messages are read into ArrayBuffers. If a partial packet arrives I need to store it and wait for the next message before re-attempting to parse it.
我正在接收和解析具有各种数据结构的网络数据包。传入的消息被读入 ArrayBuffers。如果部分数据包到达,我需要存储它并等待下一条消息,然后重新尝试解析它。
Currently I'm doing something like this:
目前我正在做这样的事情:
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;
}
Obviously you can't get around having to create a new buffer as ArrayBuffers are of a fixed length, but is it necessary to initialize typed arrays? Upon arrival I just want is to be able to treat the buffers as buffers; types and structures are of no concern.
显然,由于 ArrayBuffers 的长度是固定的,因此您无法避免创建新缓冲区,但是是否有必要初始化类型化数组?到达后,我只想能够将缓冲区视为缓冲区;类型和结构无关紧要。
采纳答案by Cyphus
You could always use DataView
(http://www.khronos.org/registry/typedarray/specs/latest/#8) rather than a specific typed array, but as has been mentioned in the comments to your question, you can't actually do much with ArrayBuffer
on its own.
您始终可以使用DataView
(http://www.khronos.org/registry/typedarray/specs/latest/#8)而不是特定的类型化数组,但正如对您的问题的评论中所述,您实际上不能自己做很多事情ArrayBuffer
。
回答by Jb Drucker
Why not using a Blob ? (I realize it might not have been available at that time).
为什么不使用 Blob ?(我意识到当时它可能不可用)。
Just create a Blob with your data, like var blob = new Blob([array1,array2,string,...])
and turn it back into an ArrayBuffer (if needed) using a FileReader (see this).
只需使用您的数据创建一个 Blob,例如var blob = new Blob([array1,array2,string,...])
并使用 FileReader 将其转换回 ArrayBuffer(如果需要)(请参阅此)。
Check this : What's the difference between BlobBuilder and the new Blob constructor?And this : MDN Blob API
检查这个:BlobBuilder 和新的 Blob 构造函数之间有什么区别?还有这个:MDN Blob API
EDIT :
编辑 :
I wanted to compare the efficiency of these two methods (Blobs, and the method used in the question) and created a JSPerf : http://jsperf.com/appending-arraybuffers
我想比较这两种方法(Blob,以及问题中使用的方法)的效率并创建了一个 JSPerf:http://jsperf.com/appending-arraybuffers
Seems like using Blobs is slower (In fact, I guess it's the use of Filereader to read the Blob that takes the most time). So now you know ;) Maybe it would me more efficient when there are more than 2 ArrayBuffer (like reconstructing a file from its chunks).
貌似使用Blob比较慢(其实我猜是使用Filereader读取Blob需要的时间最多)。所以现在你知道了 ;) 当有 2 个以上的 ArrayBuffer(比如从它的块重建文件)时,我可能会更有效率。
回答by Duco
It seems you've already concluded that there is no way around creating a new array buffer. However, for performance sake, it could be beneficial to append the contents of the buffer to a standard array object, then create a new array buffer or typed array from that.
您似乎已经得出结论,无法创建新的数组缓冲区。但是,出于性能考虑,将缓冲区的内容附加到标准数组对象,然后从中创建新的数组缓冲区或类型化数组可能是有益的。
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));
}
Most javascript engines will already have some space set aside for dynamically allocated memory. This method will utilize that space instead of creating numerous new memory allocations, which can be a performance killer inside the operating system kernel. On top of that you'll also shave off a few function calls.
大多数 javascript 引擎已经为动态分配的内存留出了一些空间。这种方法将利用该空间而不是创建大量新的内存分配,这可能是操作系统内核中的性能杀手。最重要的是,您还将减少一些函数调用。
A second, more involved option would be to allocate the memory beforehand. If you know the maximum size of any data stream then you could create an array buffer of that size, fill it up (partially if necessary) then empty it when done.
第二个更复杂的选项是预先分配内存。如果您知道任何数据流的最大大小,那么您可以创建一个该大小的数组缓冲区,将其填满(必要时部分填充),然后在完成后将其清空。
Finally, if performance is your primary goal, and you know the maximum packet size (instead of the entire stream) then start out with a handful of array buffers of that size. As you fill up your pre-allocated memory, create new buffers between network calls -- asynchronously if possible.
最后,如果性能是您的主要目标,并且您知道最大数据包大小(而不是整个流),那么从少量该大小的数组缓冲区开始。当您填满预先分配的内存时,请在网络调用之间创建新缓冲区——如果可能,异步创建。