ProtoDef-io / node-protodef

Describe your protocol, and read it with ease.
MIT License
31 stars 18 forks source link

Performance improvements #63

Closed rom1504 closed 4 years ago

rom1504 commented 8 years ago

Ideas (discussed with @roblabla)

rom1504 commented 8 years ago

https://gist.github.com/rom1504/32c452f820a71483bb59 is a decent sumary of perf by type (produced by benchmark_by_test.js)

What should be improved datatype-wise are:

I think we could probably improve everything by decreasing the overhead.

It might be interesting to benchmark a few simple function doing reading/writing but manually optimized, to see how much progress we can make.

rom1504 commented 8 years ago
var Benchmark = require('benchmark');
var ProtoDef = require("protodef").ProtoDef;
var readi8=require("./dist/datatypes/numeric")["i8"][0];

var proto=new ProtoDef();

var buf=new Buffer([0x3d]);

var suite = new Benchmark.Suite;
suite
.add('readInt8', function() {
  buf.readInt8(0);
})
.add('protodef parsePacketBuffer i8', function() {
  proto.parsePacketBuffer("i8",buf);
})
.add('protodef read i8', function() {
  proto.read(buf,0,"i8");
})
.add('protodef read i8 raw', function() {
  readi8(buf,0);
})
.on('cycle', function(event) {
  console.log(String(event.target));
})
.run({ 'async': false });

Result:

readInt8 x 33,753,530 ops/sec ±2.65% (59 runs sampled)
protodef parsePacketBuffer i8 x 365,732 ops/sec ±3.61% (77 runs sampled)
protodef read i8 x 6,396,709 ops/sec ±7.65% (60 runs sampled)
protodef read i8 raw x 18,909,880 ops/sec ±6.73% (69 runs sampled)

There is definitely some improvement to be made.

rom1504 commented 8 years ago

It seems the tryCatch is responsible for a 10x speed decrease

edit: not just the tryCatch, it's removing both the tryCatch and the big return in parsePacketBuffer that increases the perf.

edit2: but the tryCatch slow things down by at least a factor of 3.

rom1504 commented 8 years ago

The only way to avoid the overhead of read i8 raw is to define something like this:

function readByte(buffer,offset)
{
  return buffer[offset];
}

Redefining the basic buffer function.

Might be worth it.

edit: no it's not worth it because the rest of the overhead trigger some kind of deopt anyway.

rom1504 commented 8 years ago

Well.

I believe nothing short of compiling the datatype can make this actually fast. I'm done trying to make small changes, it's not an efficient way to optimize.

rom1504 commented 4 years ago

I think this is pretty much done, thanks @Karang