arr = [...buffer]
ES6 introduced a lot of other features, besides buffers.
You can even easily append like this:
arr.push(...buffer)
The ... operator expands enumerables such as arrays and buffers when used in array. It also expands them into separate function arguments.
Yes, it's also faster:
... : x100000: 835.850ms
Slice call from prototype : x100000: 2118.513ms
var array,
buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]),
iter = 100000;
array = buffer;
console.time("... : x" + iter);
for (var i = iter; i--;) array = [...buffer]
console.timeEnd("... : x" + iter);
console.time("Apply/call/etc : x" + iter);
for (var i = iter; i--;) array = Array.prototype.slice.call(buffer, 0)
console.timeEnd("Apply/call/etc : x" + iter);
Answer from user4584267 on Stack Overflowarr = [...buffer]
ES6 introduced a lot of other features, besides buffers.
You can even easily append like this:
arr.push(...buffer)
The ... operator expands enumerables such as arrays and buffers when used in array. It also expands them into separate function arguments.
Yes, it's also faster:
... : x100000: 835.850ms
Slice call from prototype : x100000: 2118.513ms
var array,
buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]),
iter = 100000;
array = buffer;
console.time("... : x" + iter);
for (var i = iter; i--;) array = [...buffer]
console.timeEnd("... : x" + iter);
console.time("Apply/call/etc : x" + iter);
for (var i = iter; i--;) array = Array.prototype.slice.call(buffer, 0)
console.timeEnd("Apply/call/etc : x" + iter);
There is another way to convert to array of integers
Using toJSON()
Buffer.from('Text of example').toJSON()
{ type: 'Buffer',data: [ 84, 101, 120, 116, 32, 111, 102, 32, 101, 120, 97, 109, 112, 108, 101 ] }
// simple get data
Buffer.from('Text of example').toJSON().data
[ 84, 101, 120, 116, 32, 111, 102, 32, 101, 120, 97, 109, 112, 108, 101 ]
Example of benchmark
// I took this from @user4584267's answer
const buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]);
let array = null;
const iterations = 100000;
console.time("...buffer");
for (let i = iterations; i=i-1;) array = [...buffer]
console.timeEnd("...buffer");
console.time("array.prototype.slice.call");
for (let i = iterations; i=i-1;) array = Array.prototype.slice.call(buffer, 0)
console.timeEnd("array.prototype.slice.call");
console.time("toJSON().data");
for (let i = iterations; i=i-1;) array = buffer.toJSON().data
console.timeEnd("toJSON().data");
OUTPUT
...buffer: 559.932ms
array.prototype.slice.call: 1176.535ms
toJSON().data: 30.571ms
or if you want more profesional and custom function in Buffer use this:
Buffer.prototype.toArrayInteger = function(){
if (this.length > 0) {
const data = new Array(this.length);
for (let i = 0; i < this.length; i=i+1)
data[i] = this[i];
return data;
}
return [];
}
Example of benchmark:
const buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]);
let array = null;
const iterations = 100000;
console.time("toArrayInteger");
for (let i = iterations; i=i-1;) buffer.toArrayInteger();
console.timeEnd("toArrayInteger");
Ouput:
toArrayInteger: 28.714ms
Note: In the last example I copied a function from Buffer.toJSON and custom it a lite
» npm install bufferlist
This portion of the bl github page more or less answers your question:
Give it a callback in the constructor and use it just like concat-stream:
const bl = require('bl') , fs = require('fs') fs.createReadStream('README.md') .pipe(bl(function (err, data) { // note 'new' isn't strictly required // `data` is a complete Buffer object containing the full data console.log(data.toString()) }))Note that when you use the callback method like this, the resulting data parameter is a concatenation of all Buffer objects in the list. If you want to avoid the overhead of this concatenation (in cases of extreme performance consciousness), then avoid the callback method and just listen to 'end' instead, like a standard Stream.
You're passing a callback to bl, which is basically a function that it will call when it has a stream of data to do something with. Thus, data is undefined for now... it's just a parameter name that will later be used to pass the text from the GET call for printing.
I believe that bl.end() doesn't have be called because there's no real performance overhead to letting it run, but I could be wrong.
I have read the source code of bl library and node stream API.
BufferList is a custom duplex stream,that is both Readable and Writable.When you run readableStream.pipe(BufferList), by default end() is called on BufferList as the destination when the source stream emits end() which fires when there will be no more data to read.
See the implementation of BufferList.prorotype.end:
BufferList.prototype.end = function (chunk) {
DuplexStream.prototype.end.call(this, chunk)
if (this._callback) {
this._callback(null, this.slice())
this._callback = null
}
}
So the callback passed to BufferList, will be called after BufferList received all data from the source stream, call this.slice() will return the result of concatenating all the Buffers in the BufferList where is the data parameter comes from.