From 91609a23433cb05a7a8792bfa1b8c378847bc525 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 29 Dec 2020 18:03:10 +0800 Subject: [PATCH] chore: add bench suite for object getter setter --- bench/bench.ts | 2 + bench/get-set-property.ts | 52 +++++++++++ bench/src/get_set_property.rs | 158 ++++++++++++++++++++++++++++++++++ bench/src/lib.rs | 6 +- 4 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 bench/get-set-property.ts create mode 100644 bench/src/get_set_property.rs diff --git a/bench/bench.ts b/bench/bench.ts index eb9d2cc0..254eb6fa 100644 --- a/bench/bench.ts +++ b/bench/bench.ts @@ -5,6 +5,7 @@ import { Summary } from 'benny/lib/internal/common-types' import { benchAsync } from './async' import { benchBuffer } from './buffer' +import { benchGetSetProperty } from './get-set-property' import { benchNoop } from './noop' import { benchPlus } from './plus' @@ -13,6 +14,7 @@ async function run() { await benchNoop(), await benchPlus(), await benchBuffer(), + await benchGetSetProperty(), await benchAsync(), ] .map(formatSummary) diff --git a/bench/get-set-property.ts b/bench/get-set-property.ts new file mode 100644 index 00000000..08915904 --- /dev/null +++ b/bench/get-set-property.ts @@ -0,0 +1,52 @@ +import b from 'benny' + +const { TestClass } = require('./index.node') + +function createClass() { + const testObject = new TestClass() + + Object.defineProperty(testObject, '_miterLimit', { + value: 10, + configurable: false, + enumerable: false, + writable: true, + }) + + Object.defineProperty(testObject, '_lineJoin', { + value: 'miter', + configurable: false, + enumerable: false, + writable: true, + }) + + return testObject +} + +export const benchGetSetProperty = () => + b.suite( + 'Get Set property', + b.add('Get Set from native#u32', () => { + const o = createClass() + o.miterNative + o.miterNative = 1 + }), + b.add('Get Set from JavaScript#u32', () => { + const o = createClass() + o.miter + o.miter = 1 + }), + + b.add('Get Set from native#string', () => { + const o = createClass() + o.lineJoinNative + o.lineJoinNative = 'bevel' + }), + b.add('Get Set from JavaScript#string', () => { + const o = createClass() + o.lineJoin + o.lineJoin = 'bevel' + }), + + b.cycle(), + b.complete(), + ) diff --git a/bench/src/get_set_property.rs b/bench/src/get_set_property.rs new file mode 100644 index 00000000..1e5d3d01 --- /dev/null +++ b/bench/src/get_set_property.rs @@ -0,0 +1,158 @@ +use std::str::FromStr; + +use napi::*; + +struct TestNative { + miter_limit: u32, + line_join: LineJoin, +} + +enum LineJoin { + Miter, + Round, + Bevel, +} + +impl LineJoin { + fn as_str(&self) -> &str { + match self { + Self::Bevel => "bevel", + Self::Miter => "miter", + Self::Round => "round", + } + } +} + +impl FromStr for LineJoin { + type Err = Error; + + fn from_str(value: &str) -> Result { + match value { + "bevel" => Ok(Self::Bevel), + "round" => Ok(Self::Round), + "miter" => Ok(Self::Miter), + _ => Err(Error::new( + Status::InvalidArg, + format!("[{}] is not valid LineJoin value", value), + )), + } + } +} + +pub fn register_js(exports: &mut JsObject, env: &Env) -> Result<()> { + let test_class = env.define_class( + "TestClass", + test_class_constructor, + &[ + Property::new(&env, "miterNative")? + .with_getter(get_miter_native) + .with_setter(set_miter_native), + Property::new(&env, "miter")? + .with_getter(get_miter) + .with_setter(set_miter), + Property::new(&env, "lineJoinNative")? + .with_getter(get_line_join_native) + .with_setter(set_line_join_native), + Property::new(&env, "lineJoin")? + .with_getter(get_line_join) + .with_setter(set_line_join), + ], + )?; + exports.set_named_property("TestClass", test_class)?; + Ok(()) +} + +#[js_function] +fn test_class_constructor(ctx: CallContext) -> Result { + let native = TestNative { + miter_limit: 10, + line_join: LineJoin::Miter, + }; + let mut this = ctx.this_unchecked::(); + ctx.env.wrap(&mut this, native)?; + ctx.env.get_undefined() +} + +#[js_function] +fn get_miter_native(ctx: CallContext) -> Result { + let this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + ctx.env.create_uint32(native.miter_limit) +} + +#[js_function(1)] +fn set_miter_native(ctx: CallContext) -> Result { + let miter: u32 = ctx.get::(0)?.get_uint32()?; + + let this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + native.miter_limit = miter; + + ctx.env.get_undefined() +} + +#[js_function] +fn get_miter(ctx: CallContext) -> Result { + let this = ctx.this_unchecked::(); + this.get_named_property("_miterLimit") +} + +#[js_function(1)] +fn set_miter(ctx: CallContext) -> Result { + let miter_number = ctx.get::(0)?; + let miter = miter_number.get_uint32()?; + + let mut this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + native.miter_limit = miter; + + this.set_named_property("_miterLimit", miter_number)?; + + ctx.env.get_undefined() +} + +#[js_function] +fn get_line_join_native(ctx: CallContext) -> Result { + let this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + ctx.env.create_string(native.line_join.as_str()) +} + +#[js_function(1)] +fn set_line_join_native(ctx: CallContext) -> Result { + let line_join_string = ctx.get::(0)?; + let line_join = line_join_string.into_utf8()?; + + let this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + native.line_join = LineJoin::from_str(line_join.as_str()?)?; + + ctx.env.get_undefined() +} + +#[js_function] +fn get_line_join(ctx: CallContext) -> Result { + let this = ctx.this_unchecked::(); + + this.get_named_property("_lineJoin") +} + +#[js_function(1)] +fn set_line_join(ctx: CallContext) -> Result { + let line_join_string = ctx.get::(0)?; + let line_join = line_join_string.into_utf8()?; + + let mut this = ctx.this_unchecked::(); + let native = ctx.env.unwrap::(&this)?; + + native.line_join = LineJoin::from_str(line_join.as_str()?)?; + + this.set_named_property("_lineJoin", line_join_string)?; + + ctx.env.get_undefined() +} diff --git a/bench/src/lib.rs b/bench/src/lib.rs index ec4badc8..a278a7be 100644 --- a/bench/src/lib.rs +++ b/bench/src/lib.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate napi_derive; -use napi::{JsObject, Result}; +use napi::{Env, JsObject, Result}; #[cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))] #[global_allocator] @@ -13,16 +13,18 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; mod async_compute; mod buffer; +mod get_set_property; mod noop; mod plus; #[module_exports] -fn init(mut exports: JsObject) -> Result<()> { +fn init(mut exports: JsObject, env: Env) -> Result<()> { exports.create_named_method("noop", noop::noop)?; async_compute::register_js(&mut exports)?; buffer::register_js(&mut exports)?; plus::register_js(&mut exports)?; + get_set_property::register_js(&mut exports, &env)?; Ok(()) }