Skip to content

Instantly share code, notes, and snippets.

@justmoon
Last active October 23, 2018 17:49
Show Gist options
  • Save justmoon/90300c1e264e99ecefcdd7f2014816fb to your computer and use it in GitHub Desktop.
Save justmoon/90300c1e264e99ecefcdd7f2014816fb to your computer and use it in GitHub Desktop.
BigNumber.js vs Long for UInt64 serialization
const Benchmark = require('benchmark')
const BigNumber = require('bignumber.js').BigNumber
const Long = require('long')
const ITERATIONS_PER_CALL = 1000
const TEST_DATA_STRINGS = new Array(ITERATIONS_PER_CALL).fill(null).map((v, i) => String(i))
const TEST_DATA_BUFFERS = TEST_DATA_STRINGS.map(str => Buffer.from(new BigNumber(str).toString(16).padStart(16, '0'), 'hex'))
const HIGH_WORD_MULTIPLIER = 0x100000000
const target = new Buffer(8)
const suite = new Benchmark.Suite()
suite
.add('Long serialize', function () {
for (let i = 0; i < ITERATIONS_PER_CALL; i++) {
const amount = Long.fromString(TEST_DATA_STRINGS[i], true)
target.writeUInt32BE(amount.getHighBitsUnsigned())
target.writeUInt32BE(amount.getLowBitsUnsigned(), 4)
}
})
.add('Bignumber.js serialize', function () {
for (let i = 0; i < ITERATIONS_PER_CALL; i++) {
const uint64 = new BigNumber(TEST_DATA_STRINGS[i])
target.writeUInt32BE(uint64.dividedToIntegerBy(HIGH_WORD_MULTIPLIER).toNumber())
target.writeUInt32BE(uint64.modulo(HIGH_WORD_MULTIPLIER).toNumber(), 4)
}
})
.add('Long deserialize', function () {
for (let i = 0; i < ITERATIONS_PER_CALL; i++) {
const highBits = TEST_DATA_BUFFERS[i].readUInt32BE()
const lowBits = TEST_DATA_BUFFERS[i].readUInt32BE(4)
Long.fromBits(+lowBits, +highBits, true).toString()
}
})
.add('Bignumber.js deserialize', function () {
for (let i = 0; i < ITERATIONS_PER_CALL; i++) {
const highBits = TEST_DATA_BUFFERS[i].readUInt32BE()
const lowBits = TEST_DATA_BUFFERS[i].readUInt32BE(4)
const uint64 = new BigNumber(highBits).times(HIGH_WORD_MULTIPLIER).plus(lowBits)
uint64.toString(10)
}
})
.on('cycle', function(event) {
console.log(String(event.target))
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.on('error', function (err) {
console.log('Error:', err)
})
.run({ async: true })
@justmoon
Copy link
Author

Results on my machine:

Long x 5,546 ops/sec ±2.75% (84 runs sampled)
Bignumber.js x 165 ops/sec ±1.94% (74 runs sampled)
Fastest is Long

@justmoon
Copy link
Author

Results with deserialization:

Long serialize x 8,195 ops/sec ±3.41% (81 runs sampled)
Bignumber.js serialize x 136 ops/sec ±9.00% (63 runs sampled)
Long deserialize x 7,317 ops/sec ±2.83% (81 runs sampled)
Bignumber.js deserialize x 708 ops/sec ±1.95% (83 runs sampled)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment