1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

perf(napi): optimize primitive napi functions (#16163)

This optimization applies on `napi_get_undefined`, `napi_get_null` &
`napi_get_boolean`.

```
# main

benchmark               time (avg)             (min … max)       p75       p99      p995
---------------------------------------------------------- -----------------------------
warmup              482.55 ps/iter   (462.5 ps … 15.67 ns)    475 ps    525 ps  829.1 ps
napi_get_undefined   25.07 ns/iter   (24.03 ns … 36.87 ns)  25.37 ns  27.09 ns  34.85 ns
```

```
# This patch

benchmark               time (avg)             (min … max)       p75       p99      p995
---------------------------------------------------------- -----------------------------
warmup              484.78 ps/iter    (462.5 ps … 14.4 ns)    475 ps  554.1 ps  583.3 ps
napi_get_undefined   15.52 ns/iter   (15.35 ns … 22.14 ns)  15.41 ns  17.18 ns  20.02 ns
```
This commit is contained in:
Divy Srivastava 2022-10-07 03:54:01 -07:00 committed by GitHub
parent be80c57b3c
commit e136bd86b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 4 deletions

View file

@ -159,6 +159,8 @@ opt-level = 3
opt-level = 3 opt-level = 3
[profile.release.package.deno_napi] [profile.release.package.deno_napi]
opt-level = 3 opt-level = 3
[profile.release.package.test_napi]
opt-level = 3
[profile.release.package.num-bigint-dig] [profile.release.package.num-bigint-dig]
opt-level = 3 opt-level = 3
[profile.release.package.v8] [profile.release.package.v8]

6
cli/bench/napi/bench.js Normal file
View file

@ -0,0 +1,6 @@
import { loadTestLibrary } from "../../../test_napi/common.js";
const lib = loadTestLibrary();
Deno.bench("warmup", () => {});
Deno.bench("napi_get_undefined", () => lib.test_get_undefined(0));

View file

@ -0,0 +1,10 @@
import { run, bench } from "mitata";
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const lib = require("../../../test_napi.node");
bench("warmup", () => {});
bench("napi_get_undefined", () => lib.test_get_undefined(0));
run();

View file

@ -1333,7 +1333,7 @@ fn napi_get_boolean(
) -> Result { ) -> Result {
let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value: v8::Local<v8::Value> = let value: v8::Local<v8::Value> =
v8::Boolean::new(&mut env.scope(), value).into(); v8::Boolean::new(env.isolate(), value).into();
*result = value.into(); *result = value.into();
Ok(()) Ok(())
} }
@ -1520,7 +1520,7 @@ fn napi_get_new_target(
fn napi_get_null(env: *mut Env, result: *mut napi_value) -> Result { fn napi_get_null(env: *mut Env, result: *mut napi_value) -> Result {
let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value: v8::Local<v8::Value> = v8::null(&mut env.scope()).into(); let value: v8::Local<v8::Value> = v8::null(env.isolate()).into();
*result = value.into(); *result = value.into();
Ok(()) Ok(())
} }
@ -1611,7 +1611,7 @@ fn napi_get_typedarray_info(
#[napi_sym::napi_sym] #[napi_sym::napi_sym]
fn napi_get_undefined(env: *mut Env, result: *mut napi_value) -> Result { fn napi_get_undefined(env: *mut Env, result: *mut napi_value) -> Result {
let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value: v8::Local<v8::Value> = v8::undefined(&mut env.scope()).into(); let value: v8::Local<v8::Value> = v8::undefined(env.isolate()).into();
*result = value.into(); *result = value.into();
Ok(()) Ok(())
} }

View file

@ -3,6 +3,7 @@ use serde::ser;
use serde::ser::Serialize; use serde::ser::Serialize;
use std::cell::RefCell; use std::cell::RefCell;
use std::ops::DerefMut;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::keys::v8_struct_key; use crate::keys::v8_struct_key;
@ -435,7 +436,8 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> {
} }
fn serialize_f64(self, v: f64) -> JsResult<'a> { fn serialize_f64(self, v: f64) -> JsResult<'a> {
Ok(v8::Number::new(&mut self.scope.borrow_mut(), v).into()) let scope = &mut self.scope.borrow_mut();
Ok(v8::Number::new(scope.deref_mut(), v).into())
} }
fn serialize_bool(self, v: bool) -> JsResult<'a> { fn serialize_bool(self, v: bool) -> JsResult<'a> {

View file

@ -10,6 +10,7 @@ pub mod callback;
pub mod coerce; pub mod coerce;
pub mod numbers; pub mod numbers;
pub mod object_wrap; pub mod object_wrap;
pub mod primitives;
pub mod promise; pub mod promise;
pub mod properties; pub mod properties;
pub mod strings; pub mod strings;
@ -67,6 +68,7 @@ unsafe extern "C" fn napi_register_module_v1(
numbers::init(env, exports); numbers::init(env, exports);
typedarray::init(env, exports); typedarray::init(env, exports);
array::init(env, exports); array::init(env, exports);
primitives::init(env, exports);
properties::init(env, exports); properties::init(env, exports);
promise::init(env, exports); promise::init(env, exports);
coerce::init(env, exports); coerce::init(env, exports);

View file

@ -0,0 +1,23 @@
use napi_sys::*;
use std::ptr;
extern "C" fn test_get_undefined(
env: napi_env,
_: napi_callback_info,
) -> napi_value {
let mut result = ptr::null_mut();
unsafe { napi_get_undefined(env, &mut result) };
result
}
pub fn init(env: napi_env, exports: napi_value) {
let properties = &[crate::new_property!(
env,
"test_get_undefined\0",
test_get_undefined
)];
unsafe {
napi_define_properties(env, exports, properties.len(), properties.as_ptr())
};
}