From b01dae728bd1925144e15155f6b3f297d184c548 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 13 May 2021 23:36:39 +0800 Subject: [PATCH] bench: add array suite --- bench/Cargo.toml | 4 +++- bench/bench.ts | 4 ++++ bench/create-array.ts | 25 ++++++++++++++++++++ bench/get-array-from-js.ts | 27 +++++++++++++++++++++ bench/src/create_array.rs | 32 +++++++++++++++++++++++++ bench/src/get_value_from_js.rs | 34 +++++++++++++++++++++++++++ bench/src/lib.rs | 4 ++++ napi/src/env.rs | 2 +- napi/src/js_values/function.rs | 2 +- napi/src/js_values/object_property.rs | 4 ++-- 10 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 bench/create-array.ts create mode 100644 bench/get-array-from-js.ts create mode 100644 bench/src/create_array.rs create mode 100644 bench/src/get_value_from_js.rs 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/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 }