Merge pull request #558 from napi-rs/bench-array

bench: add array suite
This commit is contained in:
LongYinan 2021-05-17 11:52:33 +08:00 committed by GitHub
commit 07a60125d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 142 additions and 24 deletions

View file

@ -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"]}

View file

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

25
bench/create-array.ts Normal file
View file

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

View file

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

32
bench/src/create_array.rs Normal file
View file

@ -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<JsString> {
let a: Vec<u32> = 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<JsObject> {
let a: Vec<u32> = 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<JsUnknown> {
let a: Vec<u32> = vec![42; 1000];
env.to_js_value(&a).map(Some)
}

View file

@ -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<JsUndefined> {
let input = ctx.get::<JsString>(0)?.into_utf8()?;
let _: Vec<u32> = from_str(input.as_str()?)?;
ctx.env.get_undefined()
}
#[js_function(1)]
fn get_array_from_js_array(ctx: CallContext) -> Result<JsUndefined> {
let input = ctx.get::<JsObject>(0)?;
let _: Vec<u32> = ctx.env.from_js_value(input)?;
ctx.env.get_undefined()
}
#[js_function(1)]
fn get_array_with_for_loop(ctx: CallContext) -> Result<JsUndefined> {
let input = ctx.get::<JsObject>(0)?;
let array_length = input.get_array_length_unchecked()? as usize;
let mut result: Vec<JsUnknown> = Vec::with_capacity(array_length);
for i in 0..array_length {
result.insert(i, input.get_element::<JsUnknown>(i as u32)?);
}
ctx.env.get_undefined()
}

View file

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

View file

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

View file

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

View file

@ -1292,7 +1292,7 @@ impl Env {
pub fn from_js_value<T, V>(&self, value: V) -> Result<T>
where
T: DeserializeOwned + ?Sized,
V: NapiValue,
V: NapiRaw,
{
let value = Value {
env: self.0,

View file

@ -90,7 +90,7 @@ impl JsFunction {
#[inline]
pub fn new<V>(&self, args: &[V]) -> Result<JsObject>
where
V: NapiValue,
V: NapiRaw,
{
let mut js_instance = ptr::null_mut();
let length = args.len();

View file

@ -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<T: NapiValue>(mut self, value: T) -> Self {
pub fn with_value<T: NapiRaw>(mut self, value: T) -> Self {
self.raw_descriptor.value = unsafe { T::raw(&value) };
self
}

View file

@ -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",