From 49d4b81d97c7c75778eab09a58a10bcd71f0fde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Boquet?= Date: Thu, 24 Aug 2023 12:19:38 +0200 Subject: [PATCH 1/3] Improve ObjectId serialization by around 10% --- etc/benchmarks/main.mjs | 20 +++++++++++++++++++- src/parser/serializer.ts | 10 +++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/etc/benchmarks/main.mjs b/etc/benchmarks/main.mjs index 6f48cb1f..6635efc1 100644 --- a/etc/benchmarks/main.mjs +++ b/etc/benchmarks/main.mjs @@ -25,6 +25,24 @@ await runner({ bson.lib.deserialize(documents[i], { validation: { utf8: false } }); } }); + +await runner({ + skip: false, + name: 'serialize an ObjectId', + iterations, + setup(libs) { + const bson = getCurrentLocalBSON(libs); + return Array.from({ length: 100000 }, () => ({ + _id: new bson.lib.ObjectId() + })); + }, + run(i, bson, documents) { + bson.lib.serialize({ + nextBatch: documents + }); + } +}); + //////////////////////////////////////////////////////////////////////////////////////////////////// await runner({ skip: true, @@ -102,7 +120,7 @@ await runner({ /// nextBatch simulate /// nextBatch: [ { string * 20 } * 1000 ] /// Garbage call await runner({ - skip: false, + skip: true, name: 'deserialize a large batch of documents each with an array of many strings', iterations, setup(libs) { diff --git a/src/parser/serializer.ts b/src/parser/serializer.ts index 6f75cb0a..f5f56226 100644 --- a/src/parser/serializer.ts +++ b/src/parser/serializer.ts @@ -257,14 +257,18 @@ function serializeObjectId(buffer: Uint8Array, key: string, value: ObjectId, ind buffer[index++] = 0; // Write the objectId into the shared buffer - if (isUint8Array(value.id)) { - buffer.set(value.id.subarray(0, 12), index); + const idValue = value.id; + + if (isUint8Array(idValue)) { + for (let i = 0; i < 12; i++) { + buffer[index++] = idValue[i]; + } } else { throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId'); } // Adjust index - return index + 12; + return index; } function serializeBuffer(buffer: Uint8Array, key: string, value: Uint8Array, index: number) { From 488cacc9083bde54d918dfb0ded12fdb48474b47 Mon Sep 17 00:00:00 2001 From: Warren James Date: Tue, 5 Sep 2023 13:24:26 -0400 Subject: [PATCH 2/3] test(NODE-5577): Migrate benchmark to new format --- test/bench/src/index.ts | 3 ++- .../src/suites/objectid_serialization.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/bench/src/suites/objectid_serialization.ts diff --git a/test/bench/src/index.ts b/test/bench/src/index.ts index 2de638aa..81103404 100644 --- a/test/bench/src/index.ts +++ b/test/bench/src/index.ts @@ -1,4 +1,5 @@ import { getStringDeserializationSuite } from './suites/string_deserialization'; +import { getObjectIdSerializationSuite } from './suites/objectid_serialization'; import { type PerfSendData } from './util'; import { writeFile } from 'fs'; import { cpus, totalmem } from 'os'; @@ -17,7 +18,7 @@ console.log( ].join('\n') ); -for (const suite of [getStringDeserializationSuite()]) { +for (const suite of [getStringDeserializationSuite(), getObjectIdSerializationSuite()]) { suite.run(); results.push(suite.results); } diff --git a/test/bench/src/suites/objectid_serialization.ts b/test/bench/src/suites/objectid_serialization.ts new file mode 100644 index 00000000..ef62301e --- /dev/null +++ b/test/bench/src/suites/objectid_serialization.ts @@ -0,0 +1,24 @@ +import { Suite } from '../suite'; +import * as BSON from '../../../../'; + +export function getObjectIdSerializationSuite(): Suite { + const suite = new Suite('objectid serialization'); + const data = { + docs: Array.from({ length: 1_000 }, () => new BSON.ObjectId()) + }; + + suite.task({ + name: 'ObjectId serialization', + data, + fn: objectIds => { + BSON.serialize(objectIds); + }, + iterations: 10_000, + resultUnit: 'megabytes_per_second', + transform: (runtimeMS: number) => { + return BSON.calculateObjectSize(data) / 1024 ** 2 / (runtimeMS / 1000); + } + }); + + return suite; +} From 414745f26b06fc325d9559832efb075738a1ec6f Mon Sep 17 00:00:00 2001 From: Warren James Date: Tue, 5 Sep 2023 13:31:05 -0400 Subject: [PATCH 3/3] test(NODE-5577): remove user benchmark --- etc/benchmarks/main.mjs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/etc/benchmarks/main.mjs b/etc/benchmarks/main.mjs index 6635efc1..6f48cb1f 100644 --- a/etc/benchmarks/main.mjs +++ b/etc/benchmarks/main.mjs @@ -25,24 +25,6 @@ await runner({ bson.lib.deserialize(documents[i], { validation: { utf8: false } }); } }); - -await runner({ - skip: false, - name: 'serialize an ObjectId', - iterations, - setup(libs) { - const bson = getCurrentLocalBSON(libs); - return Array.from({ length: 100000 }, () => ({ - _id: new bson.lib.ObjectId() - })); - }, - run(i, bson, documents) { - bson.lib.serialize({ - nextBatch: documents - }); - } -}); - //////////////////////////////////////////////////////////////////////////////////////////////////// await runner({ skip: true, @@ -120,7 +102,7 @@ await runner({ /// nextBatch simulate /// nextBatch: [ { string * 20 } * 1000 ] /// Garbage call await runner({ - skip: true, + skip: false, name: 'deserialize a large batch of documents each with an array of many strings', iterations, setup(libs) {