diff --git a/.gitignore b/.gitignore index 13445573..80163bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .idea/ /target +stepper-lib/target .DS_Store .repl_history *.wasm diff --git a/Cargo.lock b/Cargo.lock index 70bd66db..3553ad20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,6 +134,18 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" +[[package]] +name = "bstr" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + [[package]] name = "bumpalo" version = "3.4.0" @@ -146,6 +158,15 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +dependencies = [ + "rustc_version", +] + [[package]] name = "cc" version = "1.0.61" @@ -164,6 +185,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -251,6 +283,42 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "criterion" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" +dependencies = [ + "cast", + "itertools", +] + [[package]] name = "crossbeam-channel" version = "0.5.0" @@ -308,6 +376,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "csv" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + [[package]] name = "ctor" version = "0.1.16" @@ -595,6 +685,12 @@ dependencies = [ "indexmap", ] +[[package]] +name = "half" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177" + [[package]] name = "hashbrown" version = "0.9.1" @@ -688,6 +784,15 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "js-sys" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "jsonpath_lib" version = "0.2.5" @@ -830,6 +935,15 @@ dependencies = [ "version_check 0.9.2", ] +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -840,6 +954,18 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" + +[[package]] +name = "oorandom" +version = "11.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c" + [[package]] name = "output_vt100" version = "0.1.2" @@ -889,6 +1015,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "plotters" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d1685fbe7beba33de0330629da9d955ac75bd54f33d7b79f9a895590124f6bb" +dependencies = [ + "js-sys", + "num-traits", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "ppv-lite86" version = "0.2.9" @@ -1037,6 +1175,15 @@ dependencies = [ "thread_local", ] +[[package]] +name = "regex-automata" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", +] + [[package]] name = "regex-syntax" version = "0.6.20" @@ -1064,6 +1211,15 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b8b2cd387f744f69469aaed197954ba4c0ecdb31e02edf99b023e0df11178a" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1113,6 +1269,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_cbor" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.117" @@ -1165,11 +1331,13 @@ dependencies = [ "aqua-test-utils", "aquamarine-vm", "boolinator", + "criterion", "env_logger", "fluence", "jsonpath_lib", "log", "maplit", + "once_cell", "pretty_assertions", "serde", "serde_derive", @@ -1210,6 +1378,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.21" @@ -1250,6 +1427,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "tinytemplate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "toml" version = "0.5.7" @@ -1295,6 +1482,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -1328,6 +1521,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "walrus" version = "0.17.0" @@ -1611,6 +1815,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "web-sys" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/stepper-lib/Cargo.toml b/stepper-lib/Cargo.toml index 3b539554..1362bc36 100644 --- a/stepper-lib/Cargo.toml +++ b/stepper-lib/Cargo.toml @@ -26,11 +26,25 @@ wasm-bindgen = "0.2.68" aqua-test-utils = { path = "../crates/test-utils" } aquamarine-vm = { git = "https://github.com/fluencelabs/fce", features = ["raw-aquamarine-vm-api"] } +criterion = "0.3.3" +once_cell = "1.4.1" env_logger = "0.7.1" maplit = "1.0.2" pretty_assertions = "0.6.1" serde_json = "1.0.56" +[[bench]] +name = "call_benchmark" +harness = false + +[[bench]] +name = "chat_benchmark" +harness = false + +[[bench]] +name = "create_service_benchmark" +harness = false + [features] # indicates that this library should be compiled for the wasm bindgen target # otherwise it will be compiled to the FCE target diff --git a/stepper-lib/benches/call_benchmark.rs b/stepper-lib/benches/call_benchmark.rs new file mode 100644 index 00000000..e7515b01 --- /dev/null +++ b/stepper-lib/benches/call_benchmark.rs @@ -0,0 +1,30 @@ +use aqua_test_utils::create_aqua_vm; +use aqua_test_utils::unit_call_service; +use aquamarine_vm::AquamarineVM; +use aquamarine_vm::AquamarineVMError; +use aquamarine_vm::StepperOutcome; + +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; + +use std::cell::RefCell; + +thread_local!(static VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "test_peer_id"))); +thread_local!(static SCRIPT: String = String::from( + r#" + (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_name)) + "#, + ) +); + +fn current_peer_id_call() -> Result { + VM.with(|vm| SCRIPT.with(|script| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", "[]"))) +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("current_peer_id_call", move |b| b.iter(move || current_peer_id_call())); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/stepper-lib/benches/chat_benchmark.rs b/stepper-lib/benches/chat_benchmark.rs new file mode 100644 index 00000000..d6722e42 --- /dev/null +++ b/stepper-lib/benches/chat_benchmark.rs @@ -0,0 +1,87 @@ +use aqua_test_utils::create_aqua_vm; +use aqua_test_utils::unit_call_service; +use aquamarine_vm::vec1::Vec1; +use aquamarine_vm::AquamarineVM; +use aquamarine_vm::AquamarineVMError; +use aquamarine_vm::HostExportedFunc; +use aquamarine_vm::IValue; +use aquamarine_vm::StepperOutcome; + +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; + +use std::cell::RefCell; + +thread_local!(static RELAY_1_VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "Relay1"))); +thread_local!(static RELAY_2_VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "Relay2"))); +thread_local!(static REMOTE_VM: RefCell = RefCell::new({ + let members_call_service: HostExportedFunc = Box::new(|_, _| -> Option { + Some(IValue::Record( + Vec1::new(vec![ + IValue::S32(0), + IValue::String(String::from(r#"[["A", "Relay1"], ["B", "Relay2"]]"#)), + ]) + .unwrap(), + )) + }); + + create_aqua_vm(members_call_service, "Remote") +})); +thread_local!(static CLIENT_1_VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "A"))); +thread_local!(static CLIENT_2_VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "B"))); + +fn chat_sent_message_benchmark() -> Result { + let script = String::from( + r#" + (seq ( + (call ("Relay1" ("identity" "") () void1[])) + (seq ( + (call ("Remote" ("552196ea-b9b2-4761-98d4-8e7dba77fac4" "add") () void2[])) + (seq ( + (call ("Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") () members)) + (fold (members m + (par ( + (seq ( + (call (m.$.[1] ("identity" "") () void[])) + (call (m.$.[0] ("fgemb3" "add") () void3[])) + )) + (next m) + )) + )) + )) + )) + )) + "#, + ); + + let res = CLIENT_1_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", "[]")) + .unwrap(); + let res = RELAY_1_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res.data)) + .unwrap(); + let res = REMOTE_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res.data)) + .unwrap(); + let res_data = res.data.clone(); + let res1 = RELAY_1_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res_data)) + .unwrap(); + CLIENT_1_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res1.data)) + .unwrap(); + let res2 = RELAY_2_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res.data)) + .unwrap(); + CLIENT_2_VM.with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", res2.data)) +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("chat_send_message", move |b| { + b.iter(move || chat_sent_message_benchmark()) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/stepper-lib/benches/create_service_benchmark.rs b/stepper-lib/benches/create_service_benchmark.rs new file mode 100644 index 00000000..c42ec699 --- /dev/null +++ b/stepper-lib/benches/create_service_benchmark.rs @@ -0,0 +1,106 @@ +use aqua_test_utils::create_aqua_vm; +use aqua_test_utils::set_variables_call_service; +use aquamarine_vm::vec1::Vec1; +use aquamarine_vm::AquamarineVM; +use aquamarine_vm::AquamarineVMError; +use aquamarine_vm::HostExportedFunc; +use aquamarine_vm::IValue; +use aquamarine_vm::StepperOutcome; + +use serde_json::json; + +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; + +use std::cell::RefCell; + +thread_local!(static VM: RefCell = RefCell::new({ + let add_module_response = String::from("add_module response"); + let add_blueprint_response = String::from("add_blueprint response"); + let create_response = String::from("create response"); + + let call_service: HostExportedFunc = Box::new(move |_, args| -> Option { + let builtin_service = match &args[0] { + IValue::String(str) => str, + _ => unreachable!(), + }; + + let response = match builtin_service.as_str() { + "add_module" => add_module_response.clone(), + "add_blueprint" => add_blueprint_response.clone(), + "create" => create_response.clone(), + _ => String::from("unknown response"), + }; + + Some(IValue::Record( + Vec1::new(vec![IValue::S32(0), IValue::String(format!("\"{}\"", response))]).unwrap(), + )) + }); + + create_aqua_vm(call_service, "A") +})); + +thread_local!(static SET_VARIABLES_VM: RefCell = RefCell::new({ + let module = "greeting"; + let module_config = json!( + { + "name": module, + "mem_pages_count": 100, + "logger_enabled": true, + "wasi": { + "envs": json!({}), + "preopened_files": vec!["/tmp"], + "mapped_dirs": json!({}), + } + } + ); + + let module_bytes = json!([1, 2]); + let blueprint = json!({ "name": "blueprint", "dependencies": [module]}); + + let variables_mapping = maplit::hashmap!( + String::from("module_bytes") => module_bytes.to_string(), + String::from("module_config") => module_config.to_string(), + String::from("blueprint") => blueprint.to_string(), + ); + + create_aqua_vm(set_variables_call_service(variables_mapping), "set_variables") +})); + +fn create_service_benchmark() -> Result { + let script = String::from( + r#" + (seq ( + (seq ( + (seq ( + (call ("set_variables" ("" "") ("module_bytes") module_bytes)) + (call ("set_variables" ("" "") ("module_config") module_config)) + )) + (call ("set_variables" ("" "") ("blueprint") blueprint)) + )) + (seq ( + (call ("A" ("add_module" "") (module_bytes module_config) module)) + (seq ( + (call ("A" ("add_blueprint" "") (blueprint) blueprint_id)) + (seq ( + (call ("A" ("create" "") (blueprint_id) service_id)) + (call ("remote_peer_id" ("" "") (service_id) client_result)) + )) + )) + )) + ))"#, + ); + + let res = SET_VARIABLES_VM + .with(|vm| vm.borrow_mut().call_with_prev_data("", script.clone(), "[]", "[]")) + .unwrap(); + VM.with(|vm| vm.borrow_mut().call_with_prev_data("", script, "[]", res.data)) +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("create_service", move |b| b.iter(move || create_service_benchmark())); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/stepper-lib/tests/join.rs b/stepper-lib/tests/join.rs index 20c5438c..7cb77450 100644 --- a/stepper-lib/tests/join.rs +++ b/stepper-lib/tests/join.rs @@ -190,8 +190,6 @@ fn join_chat() { #[test] fn join() { - env_logger::init(); - let members_call_service1: HostExportedFunc = Box::new(|_, _| -> Option { Some(IValue::Record( Vec1::new(vec![IValue::S32(0), IValue::String(String::from(r#"[["A"], ["B"]]"#))]).unwrap(),