Skip to content

Commit fb76f7d

Browse files
perf optimizations, buffer index and deserialization fix
1 parent 37c8edb commit fb76f7d

File tree

5 files changed

+32
-10
lines changed

5 files changed

+32
-10
lines changed

etc/benchmarks/main.mjs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ console.log();
99

1010
////////////////////////////////////////////////////////////////////////////////////////////////////
1111
await runner({
12-
skip: false,
12+
skip: true,
1313
name: 'deserialize({ oid, string }, { validation: { utf8: false } })',
1414
iterations,
1515
setup(libs) {
@@ -58,6 +58,15 @@ await runner({
5858
}
5959
});
6060

61+
await runner({
62+
skip: false,
63+
name: 'Double Serialization',
64+
iterations,
65+
run(i, bson) {
66+
bson.lib.serialize({ d: 2.3 });
67+
}
68+
});
69+
6170
// End
6271
console.log(
6372
'Total time taken to benchmark:',

src/parser/deserializer.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,12 @@ function deserializeObject(
263263
(buffer[index++] << 16) |
264264
(buffer[index++] << 24);
265265
} else if (elementType === constants.BSON_DATA_NUMBER && promoteValues === false) {
266-
value = new Double(buffer.readDoubleLE(index));
266+
const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
267+
value = new Double(dv.getFloat64(index, true));
267268
index = index + 8;
268269
} else if (elementType === constants.BSON_DATA_NUMBER) {
269-
value = buffer.readDoubleLE(index);
270+
const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
271+
value = dv.getFloat64(index, true);
270272
index = index + 8;
271273
} else if (elementType === constants.BSON_DATA_DATE) {
272274
const lowBits =

src/parser/serializer.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ function serializeString(
7878
return index;
7979
}
8080

81+
const SPACE_FOR_FLOAT64 = new Uint8Array(8);
82+
const DV_FOR_FLOAT64 = new DataView(
83+
SPACE_FOR_FLOAT64.buffer,
84+
SPACE_FOR_FLOAT64.byteOffset,
85+
SPACE_FOR_FLOAT64.byteLength
86+
);
8187
function serializeNumber(
8288
buffer: Buffer,
8389
key: string,
@@ -118,7 +124,8 @@ function serializeNumber(
118124
index = index + numberOfWrittenBytes;
119125
buffer[index++] = 0;
120126
// Write float
121-
buffer.writeDoubleLE(value, index);
127+
DV_FOR_FLOAT64.setFloat64(0, value, true);
128+
buffer.set(SPACE_FOR_FLOAT64, index);
122129
// Adjust index
123130
index = index + 8;
124131
}
@@ -486,7 +493,8 @@ function serializeDouble(
486493
buffer[index++] = 0;
487494

488495
// Write float
489-
buffer.writeDoubleLE(value.value, index);
496+
DV_FOR_FLOAT64.setFloat64(0, value.value, true);
497+
buffer.set(SPACE_FOR_FLOAT64, index);
490498

491499
// Adjust index
492500
index = index + 8;

test/node/bson_corpus.spec.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
const Buffer = require('buffer').Buffer;
55
const BSON = require('../register-bson');
6-
const { getNodeMajor } = require('./tools/utils');
6+
const { getNodeMajor, isBrowser } = require('./tools/utils');
77
const BSONError = BSON.BSONError;
88
const EJSON = BSON.EJSON;
99

@@ -122,7 +122,7 @@ describe('BSON Corpus', function () {
122122
describe('valid-bson', function () {
123123
for (const v of valid) {
124124
it(v.description, function () {
125-
if (v.description === 'NaN with payload' && getNodeMajor() < 10) {
125+
if (v.description === 'NaN with payload' && !isBrowser() && getNodeMajor() < 10) {
126126
this.skip();
127127
}
128128

test/node/double_tests.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const BSON = require('../register-bson');
4-
const { getNodeMajor } = require('./tools/utils');
4+
const { getNodeMajor, isBrowser } = require('./tools/utils');
55
const Double = BSON.Double;
66

77
describe('Double', function () {
@@ -64,11 +64,14 @@ describe('Double', function () {
6464
});
6565

6666
it('NaN with payload', function () {
67-
if (getNodeMajor() < 10) {
67+
if (!isBrowser() && getNodeMajor() < 10) {
6868
this.skip();
6969
}
7070
let buffer = Buffer.from('120000000000F87F', 'hex');
71-
let value = buffer.readDoubleLE(0);
71+
72+
const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
73+
let value = dv.getFloat64(0, true);
74+
7275
let serializedDouble = BSON.serialize({ d: value });
7376
expect(serializedDouble.subarray(7, 15)).to.deep.equal(buffer);
7477
let { d: newVal } = BSON.deserialize(serializedDouble, { promoteValues: true });

0 commit comments

Comments
 (0)