Skip to content

Commit 78c4264

Browse files
authored
perf(NODE-5955): use pooled memory when possible (#653)
1 parent 6d343ab commit 78c4264

File tree

7 files changed

+25
-16
lines changed

7 files changed

+25
-16
lines changed

src/bson.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export function serialize(object: Document, options: SerializeOptions = {}): Uin
116116
);
117117

118118
// Create the final buffer
119-
const finishedBuffer = ByteUtils.allocate(serializationIndex);
119+
const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
120120

121121
// Copy into the finished buffer
122122
finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);

src/decimal128.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ export class Decimal128 extends BSONValue {
591591
}
592592

593593
// Encode into a buffer
594-
const buffer = ByteUtils.allocate(16);
594+
const buffer = ByteUtils.allocateUnsafe(16);
595595
index = 0;
596596

597597
// Encode the low 64 bits of the decimal

src/objectid.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export class ObjectId extends BSONValue {
177177
}
178178

179179
const inc = ObjectId.getInc();
180-
const buffer = ByteUtils.allocate(12);
180+
const buffer = ByteUtils.allocateUnsafe(12);
181181

182182
// 4-byte timestamp
183183
NumberUtils.setInt32BE(buffer, 0, time);

src/parser/deserializer.ts

+11-13
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,8 @@ function deserializeObject(
264264
value = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
265265
index = index + stringSize;
266266
} else if (elementType === constants.BSON_DATA_OID) {
267-
const oid = ByteUtils.allocate(12);
268-
oid.set(buffer.subarray(index, index + 12));
267+
const oid = ByteUtils.allocateUnsafe(12);
268+
for (let i = 0; i < 12; i++) oid[i] = buffer[index + i];
269269
value = new ObjectId(oid);
270270
index = index + 12;
271271
} else if (elementType === constants.BSON_DATA_INT && promoteValues === false) {
@@ -355,9 +355,9 @@ function deserializeObject(
355355
}
356356
} else if (elementType === constants.BSON_DATA_DECIMAL128) {
357357
// Buffer to contain the decimal bytes
358-
const bytes = ByteUtils.allocate(16);
358+
const bytes = ByteUtils.allocateUnsafe(16);
359359
// Copy the next 16 bytes into the bytes buffer
360-
bytes.set(buffer.subarray(index, index + 16), 0);
360+
for (let i = 0; i < 16; i++) bytes[i] = buffer[index + i];
361361
// Update index
362362
index = index + 16;
363363
// Assign the new Decimal128 value
@@ -398,7 +398,6 @@ function deserializeObject(
398398
}
399399
}
400400
} else {
401-
const _buffer = ByteUtils.allocate(binarySize);
402401
// If we have subtype 2 skip the 4 bytes for the size
403402
if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
404403
binarySize = NumberUtils.getInt32LE(buffer, index);
@@ -411,13 +410,12 @@ function deserializeObject(
411410
throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
412411
}
413412

414-
// Copy the data
415-
for (i = 0; i < binarySize; i++) {
416-
_buffer[i] = buffer[index + i];
417-
}
418-
419413
if (promoteBuffers && promoteValues) {
420-
value = _buffer;
414+
value = ByteUtils.allocateUnsafe(binarySize);
415+
// Copy the data
416+
for (i = 0; i < binarySize; i++) {
417+
value[i] = buffer[index + i];
418+
}
421419
} else {
422420
value = new Binary(buffer.slice(index, index + binarySize), subType);
423421
if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) {
@@ -616,8 +614,8 @@ function deserializeObject(
616614
index = index + stringSize;
617615

618616
// Read the oid
619-
const oidBuffer = ByteUtils.allocate(12);
620-
oidBuffer.set(buffer.subarray(index, index + 12), 0);
617+
const oidBuffer = ByteUtils.allocateUnsafe(12);
618+
for (let i = 0; i < 12; i++) oidBuffer[i] = buffer[index + i];
621619
const oid = new ObjectId(oidBuffer);
622620

623621
// Update the index

src/utils/byte_utils.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export type ByteUtils = {
77
toLocalBufferType(buffer: Uint8Array | ArrayBufferView | ArrayBuffer): Uint8Array;
88
/** Create empty space of size */
99
allocate: (size: number) => Uint8Array;
10+
/** Create empty space of size, use pooled memory when available */
11+
allocateUnsafe: (size: number) => Uint8Array;
1012
/** Check if two Uint8Arrays are deep equal */
1113
equals: (a: Uint8Array, b: Uint8Array) => boolean;
1214
/** Check if two Uint8Arrays are deep equal */

src/utils/node_byte_utils.ts

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type NodeJsBuffer = ArrayBufferView &
1212
};
1313
type NodeJsBufferConstructor = Omit<Uint8ArrayConstructor, 'from'> & {
1414
alloc: (size: number) => NodeJsBuffer;
15+
allocUnsafe: (size: number) => NodeJsBuffer;
1516
from(array: number[]): NodeJsBuffer;
1617
from(array: Uint8Array): NodeJsBuffer;
1718
from(array: ArrayBuffer): NodeJsBuffer;
@@ -89,6 +90,10 @@ export const nodeJsByteUtils = {
8990
return Buffer.alloc(size);
9091
},
9192

93+
allocateUnsafe(size: number): NodeJsBuffer {
94+
return Buffer.allocUnsafe(size);
95+
},
96+
9297
equals(a: Uint8Array, b: Uint8Array): boolean {
9398
return nodeJsByteUtils.toLocalBufferType(a).equals(b);
9499
},

src/utils/web_byte_utils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ export const webByteUtils = {
109109
return new Uint8Array(size);
110110
},
111111

112+
allocateUnsafe(size: number): Uint8Array {
113+
return webByteUtils.allocate(size);
114+
},
115+
112116
equals(a: Uint8Array, b: Uint8Array): boolean {
113117
if (a.byteLength !== b.byteLength) {
114118
return false;

0 commit comments

Comments
 (0)