Merge pull request #558 from napi-rs/bench-array
bench: add array suite
This commit is contained in:
commit
07a60125d5
13 changed files with 142 additions and 24 deletions
|
@ -8,8 +8,10 @@ version = "0.1.0"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
napi = {path = "../napi", features = ["napi4"]}
|
napi = {path = "../napi", features = ["napi4", "serde-json"]}
|
||||||
napi-derive = {path = "../napi-derive"}
|
napi-derive = {path = "../napi-derive"}
|
||||||
|
serde = "1"
|
||||||
|
serde_json = "1"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies]
|
[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies]
|
||||||
jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]}
|
jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import { Summary } from 'benny/lib/internal/common-types'
|
||||||
|
|
||||||
import { benchAsync } from './async'
|
import { benchAsync } from './async'
|
||||||
import { benchBuffer } from './buffer'
|
import { benchBuffer } from './buffer'
|
||||||
|
import { benchCreateArray } from './create-array'
|
||||||
|
import { benchGetArray } from './get-array-from-js'
|
||||||
import { benchGetSetProperty } from './get-set-property'
|
import { benchGetSetProperty } from './get-set-property'
|
||||||
import { benchNoop } from './noop'
|
import { benchNoop } from './noop'
|
||||||
import { benchPlus } from './plus'
|
import { benchPlus } from './plus'
|
||||||
|
@ -14,6 +16,8 @@ async function run() {
|
||||||
await benchNoop(),
|
await benchNoop(),
|
||||||
await benchPlus(),
|
await benchPlus(),
|
||||||
await benchBuffer(),
|
await benchBuffer(),
|
||||||
|
await benchCreateArray(),
|
||||||
|
await benchGetArray(),
|
||||||
await benchGetSetProperty(),
|
await benchGetSetProperty(),
|
||||||
await benchAsync(),
|
await benchAsync(),
|
||||||
]
|
]
|
||||||
|
|
25
bench/create-array.ts
Normal file
25
bench/create-array.ts
Normal 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(),
|
||||||
|
)
|
27
bench/get-array-from-js.ts
Normal file
27
bench/get-array-from-js.ts
Normal 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
32
bench/src/create_array.rs
Normal 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)
|
||||||
|
}
|
34
bench/src/get_value_from_js.rs
Normal file
34
bench/src/get_value_from_js.rs
Normal 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()
|
||||||
|
}
|
|
@ -13,7 +13,9 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
|
|
||||||
mod async_compute;
|
mod async_compute;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
|
mod create_array;
|
||||||
mod get_set_property;
|
mod get_set_property;
|
||||||
|
mod get_value_from_js;
|
||||||
mod noop;
|
mod noop;
|
||||||
mod plus;
|
mod plus;
|
||||||
|
|
||||||
|
@ -25,6 +27,8 @@ fn init(mut exports: JsObject, env: Env) -> Result<()> {
|
||||||
buffer::register_js(&mut exports)?;
|
buffer::register_js(&mut exports)?;
|
||||||
plus::register_js(&mut exports)?;
|
plus::register_js(&mut exports)?;
|
||||||
get_set_property::register_js(&mut exports, &env)?;
|
get_set_property::register_js(&mut exports, &env)?;
|
||||||
|
create_array::register_js(&mut exports)?;
|
||||||
|
get_value_from_js::register_js(&mut exports)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,8 @@ export class CreateNpmDirCommand extends Command {
|
||||||
) => {
|
) => {
|
||||||
const pkgJsonDir = config
|
const pkgJsonDir = config
|
||||||
debug(`Read content from [${chalk.yellowBright(pkgJsonDir)}]`)
|
debug(`Read content from [${chalk.yellowBright(pkgJsonDir)}]`)
|
||||||
const {
|
const { platforms, packageName, version, binaryName, content } =
|
||||||
platforms,
|
getNapiConfig(pkgJsonDir, cwd)
|
||||||
packageName,
|
|
||||||
version,
|
|
||||||
binaryName,
|
|
||||||
content,
|
|
||||||
} = getNapiConfig(pkgJsonDir, cwd)
|
|
||||||
|
|
||||||
for (const platformDetail of platforms) {
|
for (const platformDetail of platforms) {
|
||||||
const targetDir = join(
|
const targetDir = join(
|
||||||
|
|
|
@ -39,13 +39,8 @@ export class PrePublishCommand extends Command {
|
||||||
|
|
||||||
@Command.Path('prepublish')
|
@Command.Path('prepublish')
|
||||||
async execute() {
|
async execute() {
|
||||||
const {
|
const { packageJsonPath, platforms, version, packageName, binaryName } =
|
||||||
packageJsonPath,
|
getNapiConfig(this.configFileName)
|
||||||
platforms,
|
|
||||||
version,
|
|
||||||
packageName,
|
|
||||||
binaryName,
|
|
||||||
} = getNapiConfig(this.configFileName)
|
|
||||||
debug(`Update optionalDependencies in [${packageJsonPath}]`)
|
debug(`Update optionalDependencies in [${packageJsonPath}]`)
|
||||||
if (!this.isDryRun) {
|
if (!this.isDryRun) {
|
||||||
await VersionCommand.updatePackageJson(this.prefix, this.configFileName)
|
await VersionCommand.updatePackageJson(this.prefix, this.configFileName)
|
||||||
|
|
|
@ -1292,7 +1292,7 @@ impl Env {
|
||||||
pub fn from_js_value<T, V>(&self, value: V) -> Result<T>
|
pub fn from_js_value<T, V>(&self, value: V) -> Result<T>
|
||||||
where
|
where
|
||||||
T: DeserializeOwned + ?Sized,
|
T: DeserializeOwned + ?Sized,
|
||||||
V: NapiValue,
|
V: NapiRaw,
|
||||||
{
|
{
|
||||||
let value = Value {
|
let value = Value {
|
||||||
env: self.0,
|
env: self.0,
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl JsFunction {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<V>(&self, args: &[V]) -> Result<JsObject>
|
pub fn new<V>(&self, args: &[V]) -> Result<JsObject>
|
||||||
where
|
where
|
||||||
V: NapiValue,
|
V: NapiRaw,
|
||||||
{
|
{
|
||||||
let mut js_instance = ptr::null_mut();
|
let mut js_instance = ptr::null_mut();
|
||||||
let length = args.len();
|
let length = args.len();
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::convert::From;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use crate::{check_status, sys, Callback, Env, NapiValue, Result};
|
use crate::{check_status, sys, Callback, Env, NapiRaw, Result};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Property<'env> {
|
pub struct Property<'env> {
|
||||||
|
@ -56,7 +56,7 @@ impl<'env> Property<'env> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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.raw_descriptor.value = unsafe { T::raw(&value) };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
10
package.json
10
package.json
|
@ -18,12 +18,12 @@
|
||||||
"build:test:android": "yarn --cwd ./test_module build --target aarch64-linux-android",
|
"build:test:android": "yarn --cwd ./test_module build --target aarch64-linux-android",
|
||||||
"build:test:armv7": "yarn --cwd ./test_module build-armv7",
|
"build:test:armv7": "yarn --cwd ./test_module build-armv7",
|
||||||
"format": "run-p format:md format:json format:yaml format:source format:rs",
|
"format": "run-p format:md format:json format:yaml format:source format:rs",
|
||||||
"format:md": "prettier --parser markdown --write './**/*.md'",
|
"format:md": "prettier --parser markdown --write ./**/*.md",
|
||||||
"format:json": "prettier --parser json --write './**/*.json'",
|
"format:json": "prettier --parser json --write ./**/*.json",
|
||||||
"format:rs": "cargo fmt",
|
"format:rs": "cargo fmt",
|
||||||
"format:source": "prettier --config ./package.json --write './**/*.{js,ts}'",
|
"format:source": "prettier --config ./package.json --write ./**/*.{js,ts}",
|
||||||
"format:yaml": "prettier --parser yaml --write './**/*.{yml,yaml}'",
|
"format:yaml": "prettier --parser yaml --write ./**/*.{yml,yaml}",
|
||||||
"lint": "eslint -c .eslintrc.yml './cli/**/*.ts' './test_module/**/*.{ts,js}'",
|
"lint": "eslint -c .eslintrc.yml ./cli/**/*.ts ./test_module/**/*.{ts,js}",
|
||||||
"prepublishOnly": "npm run build && pinst --disable",
|
"prepublishOnly": "npm run build && pinst --disable",
|
||||||
"test": "ava",
|
"test": "ava",
|
||||||
"postinstall": "husky install",
|
"postinstall": "husky install",
|
||||||
|
|
Loading…
Reference in a new issue