|
var crypto = require('crypto'); |
|
var rounds = 5000; |
|
var arraySize = 10000; |
|
|
|
|
|
console.time('Random array generation (overhead)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var buff = getRandomArray(); |
|
buff = null; |
|
} |
|
console.timeEnd('Random array generation (overhead)'); |
|
|
|
console.log(''); |
|
console.log('Create and Load in one step:'); |
|
console.time('Node Buffer'); |
|
for (var i = 0; i < rounds; i++) { |
|
var buff = new Buffer(getRandomArray()); |
|
buff = null; |
|
} |
|
console.timeEnd('Node Buffer'); |
|
|
|
console.time('ArrayBufferView (Uint8Array)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var buff = new Uint8Array(getRandomArray()); |
|
buff = null; |
|
} |
|
console.timeEnd('ArrayBufferView (Uint8Array)'); |
|
|
|
console.log(''); |
|
console.log('Create, then Load:'); |
|
console.time('Node Buffer (Array access)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var buff = new Buffer(data.length); |
|
for (var x = 0; x < data.length; x++) { |
|
buff[x] = data[x]; |
|
} |
|
data = null; |
|
buff = null; |
|
} |
|
console.timeEnd('Node Buffer (Array access)'); |
|
|
|
console.time('Node Buffer (writeUInt8)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var buff = new Buffer(data.length); |
|
for (var x = 0; x < data.length; x++) { |
|
buff.writeUInt8(data[x], x); |
|
} |
|
data = null; |
|
buff = null; |
|
} |
|
console.timeEnd('Node Buffer (writeUInt8)'); |
|
|
|
console.time('ArrayBufferView (Uint8Array.set)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var i8 = new Uint8Array(data.length); |
|
i8.set(data); |
|
data = null; |
|
i8 = null; |
|
} |
|
console.timeEnd('ArrayBufferView (Uint8Array.set)'); |
|
|
|
console.time('ArrayBufferView (Uint8Array Array access)'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var i8 = new Uint8Array(data.length); |
|
for (var x = 0; x < data.length; x++) { |
|
i8[x] = data[x]; |
|
} |
|
data = null; |
|
i8 = null; |
|
} |
|
console.timeEnd('ArrayBufferView (Uint8Array Array access)'); |
|
|
|
console.time('DataView'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var i8 = new Uint8Array(data.length); |
|
var dv = new DataView(i8.buffer); |
|
for (var x = 0; x < data.length; x++) { |
|
dv.setUint8(x, data[x]); |
|
} |
|
data = null; |
|
i8 = null; |
|
dv = null; |
|
} |
|
console.timeEnd('DataView'); |
|
|
|
|
|
console.log(''); |
|
console.log('32-bit Big-endian numbers:'); |
|
console.time('Node Buffer'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var buff = new Buffer(data.length); // Create |
|
for (var x = 0; x < data.length; x++) { |
|
buff[x] = data[x]; // Load |
|
} |
|
|
|
// Manipulate |
|
for (var x = 0; x < buff.length-10; x++) { |
|
buff.writeUInt32BE(buff.readUInt32BE(x+5), x); |
|
} |
|
data = null; |
|
buff = null; |
|
} |
|
console.timeEnd('Node Buffer'); |
|
|
|
console.time('DataView'); |
|
for (var i = 0; i < rounds; i++) { |
|
var data = getRandomArray(); |
|
var i8 = new Uint8Array(data.length); // Create |
|
for (var x = 0; x < data.length; x++) { |
|
i8[x] = data[x]; // Load |
|
} |
|
|
|
// Manipulate |
|
var buff = new DataView(i8.buffer); |
|
for (var x = 0; x < buff.byteLength-10; x++) { |
|
buff.setUint32(x, buff.getUint32(x+5), false); |
|
} |
|
data = null; |
|
buff = null; |
|
} |
|
console.timeEnd('DataView'); |
|
|
|
|
|
function getRandomArray() { |
|
var random = crypto.randomBytes(arraySize); |
|
return Array.prototype.slice.apply(random); |
|
} |
I think what's going on here is that V8 is optimizing the cases that aren't using the Buffer object because the array of random values never changes in the loop and V8 realizes that. If you modify the code slightly you get something more along the lines of expectations:
Here we generate the random array in each loop to prevent V8 optimizations. We get JS native types to be approximately 2x slower. What results do you see when you run this modified code?