diff --git a/Cargo.toml b/Cargo.toml index e72c60d4..28562bcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,12 @@ path = "rust/benches/normal/io_bench.rs" harness = false required-features = ["native"] +[[bench]] +name = "function_call_bench" +path = "rust/benches/normal/function_call_bench.rs" +harness = false +required-features = ["native"] + # Optimize Benches [[bench]] name = "add_bench_optimize" @@ -101,6 +107,12 @@ path = "rust/benches/optimize/io_bench.rs" harness = false required-features = ["native"] +[[bench]] +name = "function_call_bench_optimize" +path = "rust/benches/optimize/function_call_bench.rs" +harness = false +required-features = ["native"] + [dependencies] napi = { version = "3.9", features = ["napi4", "serde", "serde-json"], optional = true } napi-derive = { version = "3.5", optional = true } diff --git a/rust/benches/normal/function_call_bench.rs b/rust/benches/normal/function_call_bench.rs new file mode 100644 index 00000000..dc1e50a4 --- /dev/null +++ b/rust/benches/normal/function_call_bench.rs @@ -0,0 +1,51 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +use lightvm::{ + LightVM, + types::{ + capability::Capability, runtime_config::RuntimeConfig, vmconfig::VmConfig, + }, +}; + +fn config() -> VmConfig { + VmConfig { + caps: vec![Capability::Control, Capability::Debug, Capability::Observe], + runtime_config: Some(RuntimeConfig { nightly: true }), + ..Default::default() + } +} + +fn main() { + let mut vm = LightVM::new(config()); + let raw = r#"[ + ["jump", 7], + ["func", "add", 2, 2, 6, "a", "b"], + ["get", "a"], + ["get", "b"], + ["add", "int"], + ["return"], + ["stop"], + ["export", "add"] + ]"#; + let benchmark = vm + .tools() + .bench("function_call_bench") + .expect("benchmark requires debug capability"); + benchmark.run( + || { + let mut vm = LightVM::new(config()); + vm.load(raw); + let function = vm.export("add".to_string()); + (vm, function) + }, + |(vm, function)| function.call(vm, vec![5.into(), 6.into()]), + ); +} diff --git a/rust/benches/optimize/function_call_bench.rs b/rust/benches/optimize/function_call_bench.rs new file mode 100644 index 00000000..8f30ec03 --- /dev/null +++ b/rust/benches/optimize/function_call_bench.rs @@ -0,0 +1,52 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +use lightvm::{ + LightVM, + types::{ + capability::Capability, runtime_config::RuntimeConfig, vmconfig::VmConfig, + }, +}; + +fn config() -> VmConfig { + VmConfig { + caps: vec![Capability::Control, Capability::Debug, Capability::Observe], + runtime_config: Some(RuntimeConfig { nightly: true }), + ..Default::default() + } +} + +fn main() { + let mut vm = LightVM::new(config()); + let raw = r#"[ + ["jump", 7], + ["func", "add", 2, 2, 6, "a", "b"], + ["get", "a"], + ["get", "b"], + ["add", "int"], + ["return"], + ["stop"], + ["export", "add"] + ]"#; + let tools = vm.tools(); + let optimized = tools.optimize_bytecode(raw); + let benchmark = tools + .bench("function_call_bench") + .expect("benchmark requires debug capability"); + benchmark.run( + || { + let mut vm = LightVM::new(config()); + vm.load(optimized.clone()); + let function = vm.export("add".to_string()); + (vm, function) + }, + |(vm, function)| function.call(vm, vec![5.into(), 6.into()]), + ); +} diff --git a/scripts/bench/ts-bench.js b/scripts/bench/ts-bench.js index 3aef4e5d..f6ac2464 100644 --- a/scripts/bench/ts-bench.js +++ b/scripts/bench/ts-bench.js @@ -31,7 +31,7 @@ console.log( ); execSync('cargo build --release --features node', { stdio: 'inherit', - cwd: path.resolve(__dirname, '..'), + cwd: path.resolve(__dirname, '../..'), }); console.log( `${s.bold}${s.green}✔${s.reset} ${s.bold}Rust build success!${s.reset}\n`, @@ -67,8 +67,11 @@ console.log( console.log( `${s.bold}${s.cyan}⚡${s.reset} ${s.bold}Running benchmarks...${s.reset}`, ); -const targetDir = path.join(__dirname, '../ts', 'benchmarks'); -const files = fs.readdirSync(targetDir).filter((file) => file.endsWith('.ts')); +const targetDir = path.join(rootDir, 'ts', 'benchmarks'); +const files = fs + .readdirSync(targetDir, { recursive: true }) + .filter((file) => file.endsWith('.ts')) + .sort(); files.forEach((file) => { console.log( diff --git a/ts/benchmarks/normal/add_bench.ts b/ts/benchmarks/normal/add_bench.ts new file mode 100644 index 00000000..c0b350ac --- /dev/null +++ b/ts/benchmarks/normal/add_bench.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], +}); + +const vm = new LightVM(config()); +const raw = [ + ['val', 'x'], + ['push', 5], + ['push', 8], + ['add', 'i16'], + ['set', 'x'], +]; + +vm.tools() + .bench('add_bench') + .run( + () => new LightVM(config()).load(raw), + (benchmarkVm) => benchmarkVm.run(), + ); diff --git a/ts/benchmarks/normal/assign_bench.ts b/ts/benchmarks/normal/assign_bench.ts new file mode 100644 index 00000000..f712086d --- /dev/null +++ b/ts/benchmarks/normal/assign_bench.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], +}); + +const vm = new LightVM(config()); +const raw = [ + ['val', 'x'], + ['push', 5], + ['set', 'x'], +]; + +vm.tools() + .bench('assign_bench') + .run( + () => new LightVM(config()).load(raw), + (benchmarkVm) => benchmarkVm.run(), + ); diff --git a/ts/benchmarks/normal/concat_bench.ts b/ts/benchmarks/normal/concat_bench.ts new file mode 100644 index 00000000..5042ce6f --- /dev/null +++ b/ts/benchmarks/normal/concat_bench.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], +}); + +const vm = new LightVM(config()); +const raw = [ + ['val', 'x'], + ['push', 'Hello from '], + ['push', 'LightVM!'], + ['set', 'x'], +]; + +vm.tools() + .bench('concat_bench') + .run( + () => new LightVM(config()).load(raw), + (benchmarkVm) => benchmarkVm.run(), + ); diff --git a/ts/benchmarks/normal/dead_code_bench.ts b/ts/benchmarks/normal/dead_code_bench.ts new file mode 100644 index 00000000..c45c3a97 --- /dev/null +++ b/ts/benchmarks/normal/dead_code_bench.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], +}); + +const vm = new LightVM(config()); +const raw = [ + ['push', 5], + ['push', 8], + ['add', 'i16'], + ['val', 'x'], + ['push', 9], + ['set', 'x'], +]; + +vm.tools() + .bench('dead_code_bench') + .run( + () => new LightVM(config()).load(raw), + (benchmarkVm) => benchmarkVm.run(), + ); diff --git a/ts/benchmarks/normal/function_call_bench.ts b/ts/benchmarks/normal/function_call_bench.ts new file mode 100644 index 00000000..2ce14c51 --- /dev/null +++ b/ts/benchmarks/normal/function_call_bench.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], + runtimeConfig: { nightly: true }, +}); +const raw = [ + ['jump', 7], + ['func', 'add', 2, 2, 6, 'a', 'b'], + ['get', 'a'], + ['get', 'b'], + ['add', 'int'], + ['return'], + ['stop'], + ['export', 'add'], +]; +const vm = new LightVM(config()); + +vm.tools() + .bench('function_call_bench') + .run( + () => { + const benchmarkVm = new LightVM(config()).load(raw); + return { vm: benchmarkVm, function: benchmarkVm.export('add') }; + }, + (state) => state.function.call(5, 6), + ); diff --git a/ts/benchmarks/normal/io_bench.ts b/ts/benchmarks/normal/io_bench.ts new file mode 100644 index 00000000..5684e3e3 --- /dev/null +++ b/ts/benchmarks/normal/io_bench.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], +}); + +const vm = new LightVM(config()); +const raw = [['push', 'Hello from LightVM!'], ['println']]; + +vm.tools() + .bench('io_bench') + .run( + () => new LightVM(config()).load(raw), + (benchmarkVm) => benchmarkVm.run(), + ); diff --git a/ts/benchmarks/add_bench.ts b/ts/benchmarks/optimize/add_bench.ts similarity index 92% rename from ts/benchmarks/add_bench.ts rename to ts/benchmarks/optimize/add_bench.ts index ea58e12e..43f8e920 100644 --- a/ts/benchmarks/add_bench.ts +++ b/ts/benchmarks/optimize/add_bench.ts @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -import { LightVM, Capability } from '../../dist/index.min.mjs'; +import { LightVM, Capability } from '../../../dist/index.min.mjs'; function runBenchmark() { const vm = new LightVM({ caps: [Capability.Control, Capability.Debug, Capability.Observe], diff --git a/ts/benchmarks/assign_bench.ts b/ts/benchmarks/optimize/assign_bench.ts similarity index 92% rename from ts/benchmarks/assign_bench.ts rename to ts/benchmarks/optimize/assign_bench.ts index facca0bc..1467dfa3 100644 --- a/ts/benchmarks/assign_bench.ts +++ b/ts/benchmarks/optimize/assign_bench.ts @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -import { LightVM, Capability } from '../../dist/index.min.mjs'; +import { LightVM, Capability } from '../../../dist/index.min.mjs'; function runBenchmark() { const vm = new LightVM({ caps: [Capability.Control, Capability.Debug, Capability.Observe], diff --git a/ts/benchmarks/concat_bench.ts b/ts/benchmarks/optimize/concat_bench.ts similarity index 92% rename from ts/benchmarks/concat_bench.ts rename to ts/benchmarks/optimize/concat_bench.ts index 0201b2df..6f293626 100644 --- a/ts/benchmarks/concat_bench.ts +++ b/ts/benchmarks/optimize/concat_bench.ts @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -import { LightVM, Capability } from '../../dist/index.min.mjs'; +import { LightVM, Capability } from '../../../dist/index.min.mjs'; function runBenchmark() { const vm = new LightVM({ caps: [Capability.Control, Capability.Debug, Capability.Observe], diff --git a/ts/benchmarks/dead_code_bench.ts b/ts/benchmarks/optimize/dead_code_bench.ts similarity index 87% rename from ts/benchmarks/dead_code_bench.ts rename to ts/benchmarks/optimize/dead_code_bench.ts index 7fa3fe16..4e45434d 100644 --- a/ts/benchmarks/dead_code_bench.ts +++ b/ts/benchmarks/optimize/dead_code_bench.ts @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -import { LightVM, Capability } from '../../dist/index.min.mjs'; +import { LightVM, Capability } from '../../../dist/index.min.mjs'; function runBenchmark() { const vm = new LightVM({ caps: [Capability.Control, Capability.Debug, Capability.Observe], @@ -17,6 +17,9 @@ function runBenchmark() { ['push', 5], ['push', 8], ['add', 'i16'], + ['val', 'x'], + ['push', 9], + ['set', 'x'], ]; const tools = vm.tools(); const optimized = tools.optimizeBytecode(raw); diff --git a/ts/benchmarks/optimize/function_call_bench.ts b/ts/benchmarks/optimize/function_call_bench.ts new file mode 100644 index 00000000..fd6dd925 --- /dev/null +++ b/ts/benchmarks/optimize/function_call_bench.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2026 SoTeen Studio + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { Capability, LightVM } from '../../../dist/index.min.mjs'; + +const config = () => ({ + caps: [Capability.Control, Capability.Debug, Capability.Observe], + runtimeConfig: { nightly: true }, +}); +const raw = [ + ['jump', 7], + ['func', 'add', 2, 2, 6, 'a', 'b'], + ['get', 'a'], + ['get', 'b'], + ['add', 'int'], + ['return'], + ['stop'], + ['export', 'add'], +]; +const vm = new LightVM(config()); +const tools = vm.tools(); +const optimized = tools.optimizeBytecode(raw); + +tools.bench('function_call_bench').run( + () => { + const benchmarkVm = new LightVM(config()).load(optimized); + return { vm: benchmarkVm, function: benchmarkVm.export('add') }; + }, + (state) => state.function.call(5, 6), +); diff --git a/ts/benchmarks/io_bench.ts b/ts/benchmarks/optimize/io_bench.ts similarity index 92% rename from ts/benchmarks/io_bench.ts rename to ts/benchmarks/optimize/io_bench.ts index df672c2b..b87f3471 100644 --- a/ts/benchmarks/io_bench.ts +++ b/ts/benchmarks/optimize/io_bench.ts @@ -8,7 +8,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -import { LightVM, Capability } from '../../dist/index.min.mjs'; +import { LightVM, Capability } from '../../../dist/index.min.mjs'; function runBenchmark() { const vm = new LightVM({ caps: [Capability.Control, Capability.Debug, Capability.Observe],