-
Type: Improvement
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: BSON, Performance
-
Not Needed
Use Case
As a Node.js engineer
I want to remove the need to call toLocalBufferType when using Node Buffer functions
So that I can remove an unneeded view creation and improve performance
Backstory
In the BSON library we have the ByteUtils namespace that abstracts various Buffer/Uint8Array operations needed by BSON APIs. It has a Node.js and a "web" implementation to take advantage of C++ implementations of Buffer APIs that Node.js has to offer and fallback to Uint8Array JS equivalents when Buffer isn't defined.
In order to make use of the Buffer APIs we invoke a function on every buffer input called toLocalBufferType, which helps change Uint8Arrays into Buffers so we can call instance methods like toString and swap32 on the value directly.
This conversion should not be necessary, Buffer's prototype methods should be able to operate on Uint8Arrays directly. However, that is not the case for at least toString
> Buffer.prototype.toString.call(new Uint8Array([61])) Uncaught TypeError: this.utf8Slice is not a function > Buffer.prototype.swap32.call(new Uint8Array([1, 2, 3, 4])) Uint8Array([4, 3, 2, 1])
Given this inconsistency, we convert the value. However, if we could invoke Buffer.prototype.swap32.call directly, we wouldn't potentially create a new view adding cost to GC and time spent allocating a new object.
User Experience
- What is the desired/expected outcome for the user once this ticket is implemented?
- A slight bump in perf and a little less GC
Dependencies
- Node.js core
Risks/Unknowns
- What could go wrong while implementing this change? (e.g., performance, inadvertent behavioral changes in adjacent functionality, existing tech debt, etc)
- We worsen start-up time, but potentially tolerable for the gains made at runtime
- Is there an opportunity for better cross-driver alignment or testing in this area?
- no
- Is there an opportunity to improve existing documentation on this subject?
- API docs for ByteUtils should be clear about the "feature detection" described in the AC.
Acceptance Criteria
Implementation Requirements
- Detect if the Buffer.prototype.X method supports being invoked with Uint8Array at load time. Define the ByteUtils helper using X to either directly call the prototype method or convert the value as is done now based on the outcome of the support detection.
Testing Requirements
- Use before/After hooks to modify the prototype methods to succeed and fail on Uint8Array inputs.
Documentation Requirements
- doc comments on the API/support detection logic
Follow Up Requirements
- None