Merge pull request #1279 from braydonf/readuint64lebn
Improved performance of block parsing
This commit is contained in:
commit
bbad29a76b
|
@ -14,6 +14,65 @@ console.log('Benchmarking Block/Transaction Serialization');
|
||||||
console.log('---------------------------------------');
|
console.log('---------------------------------------');
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
|
function(next) {
|
||||||
|
|
||||||
|
var buffers = [];
|
||||||
|
var hashBuffers = [];
|
||||||
|
console.log('Generating Random Test Data...');
|
||||||
|
for (var i = 0; i < 100; i++) {
|
||||||
|
|
||||||
|
// uint64le
|
||||||
|
var br = new bitcore.encoding.BufferWriter();
|
||||||
|
var num = Math.round(Math.random() * 10000000000000);
|
||||||
|
br.writeUInt64LEBN(new bitcore.crypto.BN(num));
|
||||||
|
buffers.push(br.toBuffer());
|
||||||
|
|
||||||
|
// hashes
|
||||||
|
var data = bitcore.crypto.Hash.sha256sha256(new Buffer(32));
|
||||||
|
hashBuffers.push(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = 0;
|
||||||
|
var bn;
|
||||||
|
|
||||||
|
function readUInt64LEBN() {
|
||||||
|
if (c >= buffers.length) {
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
var buf = buffers[c];
|
||||||
|
var br = new bitcore.encoding.BufferReader(buf);
|
||||||
|
bn = br.readUInt64LEBN();
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var reversed;
|
||||||
|
|
||||||
|
function readReverse() {
|
||||||
|
if (c >= hashBuffers.length) {
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
var buf = hashBuffers[c];
|
||||||
|
var br = new bitcore.encoding.BufferReader(buf);
|
||||||
|
reversed = br.readReverse();
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Starting benchmark...');
|
||||||
|
|
||||||
|
var suite = new benchmark.Suite();
|
||||||
|
suite.add('bufferReader.readUInt64LEBN()', readUInt64LEBN, {maxTime: maxTime});
|
||||||
|
suite.add('bufferReader.readReverse()', readReverse, {maxTime: maxTime});
|
||||||
|
suite
|
||||||
|
.on('cycle', function(event) {
|
||||||
|
console.log(String(event.target));
|
||||||
|
})
|
||||||
|
.on('complete', function() {
|
||||||
|
console.log('Done');
|
||||||
|
console.log('----------------------------------------------------------------------');
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
|
|
||||||
var block1;
|
var block1;
|
||||||
|
|
|
@ -91,11 +91,22 @@ BufferReader.prototype.readUInt64BEBN = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
BufferReader.prototype.readUInt64LEBN = function() {
|
BufferReader.prototype.readUInt64LEBN = function() {
|
||||||
var buf = this.buf.slice(this.pos, this.pos + 8);
|
var second = this.buf.readUInt32LE(this.pos);
|
||||||
var reversebuf = BufferReader({
|
var first = this.buf.readUInt32LE(this.pos + 4);
|
||||||
buf: buf
|
var combined = (first * 0x100000000) + second;
|
||||||
}).readReverse();
|
// Instantiating an instance of BN with a number is faster than with an
|
||||||
var bn = BN.fromBuffer(reversebuf);
|
// array or string. However, the maximum safe number for a double precision
|
||||||
|
// floating point is 2 ^ 52 - 1 (0x1fffffffffffff), thus we can safely use
|
||||||
|
// non-floating point numbers less than this amount (52 bits). And in the case
|
||||||
|
// that the number is larger, we can instatiate an instance of BN by passing
|
||||||
|
// an array from the buffer (slower) and specifying the endianness.
|
||||||
|
var bn;
|
||||||
|
if (combined <= 0x1fffffffffffff) {
|
||||||
|
bn = new BN(combined);
|
||||||
|
} else {
|
||||||
|
var data = Array.prototype.slice.call(this.buf, this.pos, this.pos + 8);
|
||||||
|
bn = new BN(data, 10, 'le');
|
||||||
|
}
|
||||||
this.pos = this.pos + 8;
|
this.pos = this.pos + 8;
|
||||||
return bn;
|
return bn;
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,7 +152,6 @@ module.exports = {
|
||||||
* @return {Buffer}
|
* @return {Buffer}
|
||||||
*/
|
*/
|
||||||
reverse: function reverse(param) {
|
reverse: function reverse(param) {
|
||||||
$.checkArgumentType(param, 'Buffer', 'param');
|
|
||||||
var ret = new buffer.Buffer(param.length);
|
var ret = new buffer.Buffer(param.length);
|
||||||
for (var i = 0; i < param.length; i++) {
|
for (var i = 0; i < param.length; i++) {
|
||||||
ret[i] = param[param.length - i - 1];
|
ret[i] = param[param.length - i - 1];
|
||||||
|
|
|
@ -190,6 +190,13 @@ describe('BufferReader', function() {
|
||||||
br.readUInt64LEBN().toNumber().should.equal(1);
|
br.readUInt64LEBN().toNumber().should.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return 10BTC', function() {
|
||||||
|
var tenbtc = 10 * 1e8;
|
||||||
|
var tenbtcBuffer = new Buffer('00ca9a3b00000000', 'hex');
|
||||||
|
var br = new BufferReader(tenbtcBuffer);
|
||||||
|
br.readUInt64LEBN().toNumber().should.equal(tenbtc);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return 2^30', function() {
|
it('should return 2^30', function() {
|
||||||
var buf = new Buffer(8);
|
var buf = new Buffer(8);
|
||||||
buf.fill(0);
|
buf.fill(0);
|
||||||
|
@ -198,6 +205,35 @@ describe('BufferReader', function() {
|
||||||
br.readUInt64LEBN().toNumber().should.equal(Math.pow(2, 30));
|
br.readUInt64LEBN().toNumber().should.equal(Math.pow(2, 30));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return 2^32 + 1', function() {
|
||||||
|
var num = Math.pow(2, 32) + 1;
|
||||||
|
var numBuffer = new Buffer('0100000001000000', 'hex');
|
||||||
|
var br = new BufferReader(numBuffer);
|
||||||
|
br.readUInt64LEBN().toNumber().should.equal(num);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return max number of satoshis', function() {
|
||||||
|
var maxSatoshis = 21000000 * 1e8;
|
||||||
|
var maxSatoshisBuffer = new Buffer('0040075af0750700', 'hex');
|
||||||
|
var br = new BufferReader(maxSatoshisBuffer);
|
||||||
|
br.readUInt64LEBN().toNumber().should.equal(maxSatoshis);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 2^53 - 1', function() {
|
||||||
|
var maxSafe = Math.pow(2, 53) - 1;
|
||||||
|
var maxSafeBuffer = new Buffer('ffffffffffff1f00', 'hex');
|
||||||
|
var br = new BufferReader(maxSafeBuffer);
|
||||||
|
br.readUInt64LEBN().toNumber().should.equal(maxSafe);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 2^53', function() {
|
||||||
|
var bn = new BN('20000000000000', 16);
|
||||||
|
var bnBuffer = new Buffer('0000000000002000', 'hex');
|
||||||
|
var br = new BufferReader(bnBuffer);
|
||||||
|
var readbn = br.readUInt64LEBN();
|
||||||
|
readbn.cmp(bn).should.equal(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return 0', function() {
|
it('should return 0', function() {
|
||||||
var buf = new Buffer(8);
|
var buf = new Buffer(8);
|
||||||
buf.fill(0);
|
buf.fill(0);
|
||||||
|
|
|
@ -152,10 +152,5 @@ describe('buffer utils', function() {
|
||||||
original[1].should.equal(reversed[1]);
|
original[1].should.equal(reversed[1]);
|
||||||
original[2].should.equal(reversed[0]);
|
original[2].should.equal(reversed[0]);
|
||||||
});
|
});
|
||||||
it('checks the argument type', function() {
|
|
||||||
expect(function() {
|
|
||||||
BufferUtil.reverse('invalid');
|
|
||||||
}).to.throw(errors.InvalidArgumentType);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue