Merge pull request #393 from napi-rs/bench-get-set

chore: add bench suite for object getter setter
This commit is contained in:
LongYinan 2020-12-29 18:20:34 +08:00 committed by GitHub
commit a3658891cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 216 additions and 2 deletions

View file

@ -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)

52
bench/get-set-property.ts Normal file
View file

@ -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(),
)

View file

@ -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<LineJoin> {
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<JsUndefined> {
let native = TestNative {
miter_limit: 10,
line_join: LineJoin::Miter,
};
let mut this = ctx.this_unchecked::<JsObject>();
ctx.env.wrap(&mut this, native)?;
ctx.env.get_undefined()
}
#[js_function]
fn get_miter_native(ctx: CallContext) -> Result<JsNumber> {
let this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&this)?;
ctx.env.create_uint32(native.miter_limit)
}
#[js_function(1)]
fn set_miter_native(ctx: CallContext) -> Result<JsUndefined> {
let miter: u32 = ctx.get::<JsNumber>(0)?.get_uint32()?;
let this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&this)?;
native.miter_limit = miter;
ctx.env.get_undefined()
}
#[js_function]
fn get_miter(ctx: CallContext) -> Result<JsUnknown> {
let this = ctx.this_unchecked::<JsObject>();
this.get_named_property("_miterLimit")
}
#[js_function(1)]
fn set_miter(ctx: CallContext) -> Result<JsUndefined> {
let miter_number = ctx.get::<JsNumber>(0)?;
let miter = miter_number.get_uint32()?;
let mut this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&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<JsString> {
let this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&this)?;
ctx.env.create_string(native.line_join.as_str())
}
#[js_function(1)]
fn set_line_join_native(ctx: CallContext) -> Result<JsUndefined> {
let line_join_string = ctx.get::<JsString>(0)?;
let line_join = line_join_string.into_utf8()?;
let this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&this)?;
native.line_join = LineJoin::from_str(line_join.as_str()?)?;
ctx.env.get_undefined()
}
#[js_function]
fn get_line_join(ctx: CallContext) -> Result<JsUnknown> {
let this = ctx.this_unchecked::<JsObject>();
this.get_named_property("_lineJoin")
}
#[js_function(1)]
fn set_line_join(ctx: CallContext) -> Result<JsUndefined> {
let line_join_string = ctx.get::<JsString>(0)?;
let line_join = line_join_string.into_utf8()?;
let mut this = ctx.this_unchecked::<JsObject>();
let native = ctx.env.unwrap::<TestNative>(&this)?;
native.line_join = LineJoin::from_str(line_join.as_str()?)?;
this.set_named_property("_lineJoin", line_join_string)?;
ctx.env.get_undefined()
}

View file

@ -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(())
}