diff --git a/bench/Cargo.toml b/bench/Cargo.toml index ddfa7d2e..f1d0cf5f 100644 --- a/bench/Cargo.toml +++ b/bench/Cargo.toml @@ -8,8 +8,10 @@ version = "0.1.0" crate-type = ["cdylib"] [dependencies] -napi = {path = "../napi", features = ["napi4"]} +napi = {path = "../napi", features = ["napi4", "serde-json"]} napi-derive = {path = "../napi-derive"} +serde = "1" +serde_json = "1" [target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies] jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]} diff --git a/bench/bench.ts b/bench/bench.ts index 254eb6fa..717f3181 100644 --- a/bench/bench.ts +++ b/bench/bench.ts @@ -5,6 +5,8 @@ import { Summary } from 'benny/lib/internal/common-types' import { benchAsync } from './async' import { benchBuffer } from './buffer' +import { benchCreateArray } from './create-array' +import { benchGetArray } from './get-array-from-js' import { benchGetSetProperty } from './get-set-property' import { benchNoop } from './noop' import { benchPlus } from './plus' @@ -14,6 +16,8 @@ async function run() { await benchNoop(), await benchPlus(), await benchBuffer(), + await benchCreateArray(), + await benchGetArray(), await benchGetSetProperty(), await benchAsync(), ] diff --git a/bench/create-array.ts b/bench/create-array.ts new file mode 100644 index 00000000..65d668fb --- /dev/null +++ b/bench/create-array.ts @@ -0,0 +1,25 @@ +import b from 'benny' + +const { + createArrayJson, + createArray, + createArrayWithSerdeTrait, +} = require('./index.node') + +export const benchCreateArray = () => + b.suite( + 'createArray', + b.add('createArrayJson', () => { + JSON.parse(createArrayJson()) + }), + b.add('create array for loop', () => { + createArray() + }), + + b.add('create array with serde trait', () => { + createArrayWithSerdeTrait() + }), + + b.cycle(), + b.complete(), + ) diff --git a/bench/get-array-from-js.ts b/bench/get-array-from-js.ts new file mode 100644 index 00000000..bde32f45 --- /dev/null +++ b/bench/get-array-from-js.ts @@ -0,0 +1,27 @@ +import b from 'benny' + +const { + getArrayFromJson, + getArrayFromJsArray, + getArrayWithForLoop, +} = require('./index.node') + +const FIXTURE = Array.from({ length: 1000 }).fill(42) + +export const benchGetArray = () => + b.suite( + 'getArrayFromJs', + b.add('get array from json string', () => { + getArrayFromJson(JSON.stringify(FIXTURE)) + }), + b.add('get array from serde', () => { + getArrayFromJsArray(FIXTURE) + }), + + b.add('get array with for loop', () => { + getArrayWithForLoop(FIXTURE) + }), + + b.cycle(), + b.complete(), + ) diff --git a/bench/src/create_array.rs b/bench/src/create_array.rs new file mode 100644 index 00000000..d8d97640 --- /dev/null +++ b/bench/src/create_array.rs @@ -0,0 +1,32 @@ +use napi::{ContextlessResult, Env, JsObject, JsString, JsUnknown, Result}; +use serde_json::to_string; + +pub fn register_js(exports: &mut JsObject) -> Result<()> { + exports.create_named_method("createArrayJson", create_array_json)?; + exports.create_named_method("createArray", create_array)?; + exports.create_named_method("createArrayWithSerdeTrait", create_array_with_serde_trait)?; + Ok(()) +} + +#[contextless_function] +pub fn create_array_json(env: Env) -> ContextlessResult { + let a: Vec = vec![42; 1000]; + let arr_string = to_string(&a)?; + env.create_string(arr_string.as_str()).map(Some) +} + +#[contextless_function] +pub fn create_array(env: Env) -> ContextlessResult { + let a: Vec = vec![42; 1000]; + let mut ret = env.create_array_with_length(a.len())?; + for (index, item) in a.iter().enumerate() { + ret.set_element(index as u32, env.create_uint32(*item)?)?; + } + Ok(Some(ret)) +} + +#[contextless_function] +pub fn create_array_with_serde_trait(env: Env) -> ContextlessResult { + let a: Vec = vec![42; 1000]; + env.to_js_value(&a).map(Some) +} diff --git a/bench/src/get_value_from_js.rs b/bench/src/get_value_from_js.rs new file mode 100644 index 00000000..71f2743d --- /dev/null +++ b/bench/src/get_value_from_js.rs @@ -0,0 +1,34 @@ +use napi::{CallContext, JsObject, JsString, JsUndefined, JsUnknown, Result}; +use serde_json::from_str; + +pub fn register_js(exports: &mut JsObject) -> Result<()> { + exports.create_named_method("getArrayFromJson", get_array_from_json)?; + exports.create_named_method("getArrayFromJsArray", get_array_from_js_array)?; + exports.create_named_method("getArrayWithForLoop", get_array_with_for_loop)?; + Ok(()) +} + +#[js_function(1)] +fn get_array_from_json(ctx: CallContext) -> Result { + let input = ctx.get::(0)?.into_utf8()?; + let _: Vec = from_str(input.as_str()?)?; + ctx.env.get_undefined() +} + +#[js_function(1)] +fn get_array_from_js_array(ctx: CallContext) -> Result { + let input = ctx.get::(0)?; + let _: Vec = ctx.env.from_js_value(input)?; + ctx.env.get_undefined() +} + +#[js_function(1)] +fn get_array_with_for_loop(ctx: CallContext) -> Result { + let input = ctx.get::(0)?; + let array_length = input.get_array_length_unchecked()? as usize; + let mut result: Vec = Vec::with_capacity(array_length); + for i in 0..array_length { + result.insert(i, input.get_element::(i as u32)?); + } + ctx.env.get_undefined() +} diff --git a/bench/src/lib.rs b/bench/src/lib.rs index a278a7be..196a6fdf 100644 --- a/bench/src/lib.rs +++ b/bench/src/lib.rs @@ -13,7 +13,9 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; mod async_compute; mod buffer; +mod create_array; mod get_set_property; +mod get_value_from_js; mod noop; mod plus; @@ -25,6 +27,8 @@ fn init(mut exports: JsObject, env: Env) -> Result<()> { buffer::register_js(&mut exports)?; plus::register_js(&mut exports)?; get_set_property::register_js(&mut exports, &env)?; + create_array::register_js(&mut exports)?; + get_value_from_js::register_js(&mut exports)?; Ok(()) } diff --git a/cli/src/create-npm-dir.ts b/cli/src/create-npm-dir.ts index 28cbfe44..d7b57f03 100644 --- a/cli/src/create-npm-dir.ts +++ b/cli/src/create-npm-dir.ts @@ -24,13 +24,8 @@ export class CreateNpmDirCommand extends Command { ) => { const pkgJsonDir = config debug(`Read content from [${chalk.yellowBright(pkgJsonDir)}]`) - const { - platforms, - packageName, - version, - binaryName, - content, - } = getNapiConfig(pkgJsonDir, cwd) + const { platforms, packageName, version, binaryName, content } = + getNapiConfig(pkgJsonDir, cwd) for (const platformDetail of platforms) { const targetDir = join( diff --git a/cli/src/pre-publish.ts b/cli/src/pre-publish.ts index 9846c7fe..45a00e1b 100644 --- a/cli/src/pre-publish.ts +++ b/cli/src/pre-publish.ts @@ -39,13 +39,8 @@ export class PrePublishCommand extends Command { @Command.Path('prepublish') async execute() { - const { - packageJsonPath, - platforms, - version, - packageName, - binaryName, - } = getNapiConfig(this.configFileName) + const { packageJsonPath, platforms, version, packageName, binaryName } = + getNapiConfig(this.configFileName) debug(`Update optionalDependencies in [${packageJsonPath}]`) if (!this.isDryRun) { await VersionCommand.updatePackageJson(this.prefix, this.configFileName) diff --git a/napi/src/env.rs b/napi/src/env.rs index 31bc3347..717aa8cd 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -1292,7 +1292,7 @@ impl Env { pub fn from_js_value(&self, value: V) -> Result where T: DeserializeOwned + ?Sized, - V: NapiValue, + V: NapiRaw, { let value = Value { env: self.0, diff --git a/napi/src/js_values/function.rs b/napi/src/js_values/function.rs index 699a17b9..9de510d9 100644 --- a/napi/src/js_values/function.rs +++ b/napi/src/js_values/function.rs @@ -90,7 +90,7 @@ impl JsFunction { #[inline] pub fn new(&self, args: &[V]) -> Result where - V: NapiValue, + V: NapiRaw, { let mut js_instance = ptr::null_mut(); let length = args.len(); diff --git a/napi/src/js_values/object_property.rs b/napi/src/js_values/object_property.rs index 44745205..8a68b745 100644 --- a/napi/src/js_values/object_property.rs +++ b/napi/src/js_values/object_property.rs @@ -2,7 +2,7 @@ use std::convert::From; use std::ffi::CString; use std::ptr; -use crate::{check_status, sys, Callback, Env, NapiValue, Result}; +use crate::{check_status, sys, Callback, Env, NapiRaw, Result}; #[derive(Clone, Copy)] pub struct Property<'env> { @@ -56,7 +56,7 @@ impl<'env> Property<'env> { } #[inline] - pub fn with_value(mut self, value: T) -> Self { + pub fn with_value(mut self, value: T) -> Self { self.raw_descriptor.value = unsafe { T::raw(&value) }; self } diff --git a/package.json b/package.json index a4f4b74b..aa6b75b8 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,12 @@ "build:test:android": "yarn --cwd ./test_module build --target aarch64-linux-android", "build:test:armv7": "yarn --cwd ./test_module build-armv7", "format": "run-p format:md format:json format:yaml format:source format:rs", - "format:md": "prettier --parser markdown --write './**/*.md'", - "format:json": "prettier --parser json --write './**/*.json'", + "format:md": "prettier --parser markdown --write ./**/*.md", + "format:json": "prettier --parser json --write ./**/*.json", "format:rs": "cargo fmt", - "format:source": "prettier --config ./package.json --write './**/*.{js,ts}'", - "format:yaml": "prettier --parser yaml --write './**/*.{yml,yaml}'", - "lint": "eslint -c .eslintrc.yml './cli/**/*.ts' './test_module/**/*.{ts,js}'", + "format:source": "prettier --config ./package.json --write ./**/*.{js,ts}", + "format:yaml": "prettier --parser yaml --write ./**/*.{yml,yaml}", + "lint": "eslint -c .eslintrc.yml ./cli/**/*.ts ./test_module/**/*.{ts,js}", "prepublishOnly": "npm run build && pinst --disable", "test": "ava", "postinstall": "husky install",