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:
parent
be80c57b3c
commit
e136bd86b3
7 changed files with 49 additions and 4 deletions
|
@ -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
6
cli/bench/napi/bench.js
Normal 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));
|
10
cli/bench/napi/bench_node.mjs
Normal file
10
cli/bench/napi/bench_node.mjs
Normal 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();
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
23
test_napi/src/primitives.rs
Normal file
23
test_napi/src/primitives.rs
Normal 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())
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue