keichi / binary-parser

A blazing-fast declarative parser builder for binary data
MIT License
868 stars 136 forks source link

Improve array performance #157

Closed mohd-akram closed 4 years ago

mohd-akram commented 4 years ago

If length was a function, it was being called with every iteration.

keichi commented 4 years ago

Nice catch! I'm just curious how much performance this improves. Do you have any performance numbers?

mohd-akram commented 4 years ago

Just did a few tests, it's about 25-30% faster:

const { Parser } = require('./dist/binary_parser');
let x = false;
function calculateLength(res) {
  if (!x) { console.log('calculating length', res); x = true; }
  return res.size;
};
const parser = Parser.start().uint32('size').array('items', {
  type: 'uint8', length: function() { return calculateLength(this); }
});
const count = 1000000;
const buffer = Buffer.allocUnsafe(count);
buffer.writeUInt32BE(count - 4);
console.time('parse array');
const res = parser.parse(buffer);
console.timeEnd('parse array');
console.log('length:', res.items.length);

There's also a correctness issue which this PR fixes - if the length call has side effects (like the console.log above), it needs a guard.

keichi commented 4 years ago

Great, the improvement should be even larger for complex functions.