Skip to content

Expose v8::String::NewExternalOneByte and v8::String::NewExternalTwoByte to Node-API #48198

Description

@Brooooooklyn

What is the problem this feature will solve?

Provide a faster way to create JavaScript string from static str

What is the feature you are proposing to solve the problem?

v8::String::NewExternalOneByte and v8::String::NewExternalTwoByte

What alternatives have you considered?

No response

Activity

  1. bnoordhuis commented on May 27, 2023

    @bnoordhuis
    Member

    Cross-engine portability is one of the n-api design goals and I don't think other engines have functionality that is similar enough. For instance, I'm fairly sure quickjs doesn't have a concept of non-owned strings.

    I suppose n-api targeting other engines could copy the string to the JS heap but having APis with wildly different performance across engines isn't great.

  2. Flarna commented on May 30, 2023

    @Flarna
    Member

    Other engines could add such APIs if at some day node is seen as relevant user.
    Not exposing any optimized APIs results in keeping NAPI slower than actually needed. It's quite a pain if one knows that moving from v8 to napi results in significant added overhead.
    I'm not saying here that this added overhead is the standard case/relevant all the time.

  3. Jamesernator commented on May 30, 2023

    @Jamesernator

    For something comparable, the current Chrome implementation of webassembly stringref proposal implements string.from_code_point for similar performance reasons.

    It would probably make sense to at least have napi_create_string_code_point if WASM does adopt this as presumably all engines would have a faster path for the creation of such strings (which is expected as no decoding would be neccessary for such an instruction).

  4. gabrielschulhof commented on Jun 1, 2023

    @gabrielschulhof
    Contributor

    We've had problems with Electron not supporting external Buffers: nodejs/node-addon-api#1257. I'm not opposed to this proposal though. I think it's fine to fall back to regular string creation.

  5. gabrielschulhof commented on Jun 1, 2023

    @gabrielschulhof
    Contributor

    BTW, is there an example of usage somewhere? Who manages the life cycle of the ExternalOneByteStringResource?

  6. Brooooooklyn commented on Jun 1, 2023

    @Brooooooklyn
    Author

    is there an example of usage somewhere?

    I think the most common usage scenario is create JavaScript String from static string, like: denoland/deno#18051. There are also use cases in NAPI-RS:

  7. Brooooooklyn commented on Jun 1, 2023

    @Brooooooklyn
    Author

    We've had problems with Electron not supporting external Buffers

    Yes, I handled it in NAPI-RS, too. I don't think it's a problem if we have a fallback strategy: https://github.com/napi-rs/napi-rs/blob/main/crates/napi/src/bindgen_runtime/js_values/buffer.rs#L245

  8. gabrielschulhof commented on Jun 1, 2023

    @gabrielschulhof
    Contributor

    @Brooooooklyn

      let core_str =
        v8::String::new_external_onebyte_static(scope, b"core").unwrap();

    It looks like the rust bindings for V8 have some mechanism for creating a static v8::ExternalStringResource to wrap the string literal. I don't think we can do that in Node-API without exposing v8::ExternalStringResource itself.

    I think the only way to go is to heap-allocate v8::ExternalStringResource and tie it via a weak reference to the resulting string, to be freed when the string is garbage-collected. This would likely make it slower, not faster, and more memory intensive too, unless the string is sizable.

  9. gabrielschulhof commented on Jun 2, 2023

    @gabrielschulhof
    Contributor

    We decided at the 2023-06-02 Node-API meeting that we will implement this as a best-effort optimization.

    • The function signatures will be exactly the same as napi_create_string_*
    • We will create a v8::ExternalStringResource for each string on the heap, and delete it using a weak reference to the resulting string.
    • We will fall back to napi_create_string_* if we cannot use external pointers (such as when pointercage is on).
    • We will document that optimized performance is not guaranteed, and because of that, modifying the string on the native side may or may not be reflected on the JS side.
  10. linked a pull request that will close this issue48198 node api external strings #48339on Jun 8, 2023
  11. added a commit that references this issue on Jul 3, 2023
  12. added a commit that references this issue on Feb 18, 2024
  13. moved this from Awaiting Triage to Triaged in Node.js feature requestson Jun 26, 2024
  14. moved this from Triaged to Done in Node.js feature requestson Aug 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

feature requestIssues requesting new Node.js features.node-apiIssues and PRs related to Node-API.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions