Skip to content

Avoid cloning during serialization #277

@wprzytula

Description

@wprzytula

Currently

As of #275, serialization consists of the following phases:

  1. JS Encoder serializes each value into a dedicated Buffer.
  2. An array of Buffers is passed to Rust's async function. FromNapiValue::from_napi_value() is called for every Buffer, and it clones it to Vec each, encapsulated in EncodedParameterWrapper, which trivially implements SerializeValue. The cloning is done in order to not be constrained by the lifetime of the Buffers, because the async function's lifetime is independent from that of Buffers.
  3. Rust Driver's execute_unpaged() is called with the resulting Vec<EncodedParameterWrapper>, which internally constructs a new SerializedValues.

Proposed optimisation

Copying Buffer's contents into Vecs is wasteful. Let's instead populate SerializedValues straight with the contents of Buffers, in synchronous context.
One idea is to have two separate NAPI calls: one (synchronous) to construct SerializedValues, and the second (asynchronous) to call execute_unpaged() with those SerializedValues. Note that Rust Driver, due to type safety concerns, purposely does not accept SerializedValues. This means we need to expose a new public Rust Driver API, simply behind the dedicated nodejs-unstable flag (analogous to the existing cpp_rust_unstable, which accepts SerializedValues.

Another (possibly more efficient) option is to have a single NAPI call, which consists of the sync part (with SerializedValues constructor straight from Buffers) and the manually configured async part (which runs Rust Driver's execute_unpaged). This is the idea of @adespawn.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions