Add redux_regex test.
# Conflicts: # benches/wasm-kernel/Cargo.toml
This commit is contained in:
parent
ed4645b23a
commit
c31498b8cc
|
@ -6,3 +6,4 @@ authors = ["Sergey Pepyakin <s.pepyakin@gmail.com>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmi = { path = ".." }
|
wasmi = { path = ".." }
|
||||||
assert_matches = "1.2"
|
assert_matches = "1.2"
|
||||||
|
wabt = "0.3"
|
||||||
|
|
|
@ -4,6 +4,7 @@ extern crate test;
|
||||||
extern crate wasmi;
|
extern crate wasmi;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate assert_matches;
|
extern crate assert_matches;
|
||||||
|
extern crate wabt;
|
||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -95,11 +96,55 @@ fn bench_rev_comp(b: &mut Bencher) {
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
let result = memory
|
let result = memory
|
||||||
.get(output_data_mem_offset, REVCOMP_INPUT.len())
|
.get(output_data_mem_offset, REVCOMP_OUTPUT.len())
|
||||||
.expect("can't get result data from a wasm memory");
|
.expect("can't get result data from a wasm memory");
|
||||||
assert_eq!(&*result, REVCOMP_OUTPUT);
|
assert_eq!(&*result, REVCOMP_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_regex_redux(b: &mut Bencher) {
|
||||||
|
let wasm_kernel = load_from_file(
|
||||||
|
"./wasm-kernel/target/wasm32-unknown-unknown/release/wasm_kernel.wasm",
|
||||||
|
).expect("failed to load wasm_kernel. Is `build.rs` broken?");
|
||||||
|
|
||||||
|
let instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default())
|
||||||
|
.expect("failed to instantiate wasm module")
|
||||||
|
.assert_no_start();
|
||||||
|
|
||||||
|
// Allocate buffers for the input and output.
|
||||||
|
let test_data_ptr: RuntimeValue = {
|
||||||
|
let input_size = RuntimeValue::I32(REVCOMP_INPUT.len() as i32);
|
||||||
|
assert_matches!(
|
||||||
|
instance.invoke_export("prepare_regex_redux", &[input_size], &mut NopExternals),
|
||||||
|
Ok(Some(v @ RuntimeValue::I32(_))) => v,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the pointer to the input buffer.
|
||||||
|
let input_data_mem_offset = assert_matches!(
|
||||||
|
instance.invoke_export("regex_redux_input_ptr", &[test_data_ptr], &mut NopExternals),
|
||||||
|
Ok(Some(RuntimeValue::I32(v))) => v as u32,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy test data inside the wasm memory.
|
||||||
|
let memory = instance.export_by_name("memory")
|
||||||
|
.expect("Expected export with a name 'memory'")
|
||||||
|
.as_memory()
|
||||||
|
.expect("'memory' should be a memory instance")
|
||||||
|
.clone();
|
||||||
|
memory
|
||||||
|
.set(input_data_mem_offset, REVCOMP_INPUT)
|
||||||
|
.expect("can't load test data into a wasm memory");
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
instance
|
||||||
|
.invoke_export("bench_regex_redux", &[test_data_ptr], &mut NopExternals)
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn fac_recursive(b: &mut Bencher) {
|
fn fac_recursive(b: &mut Bencher) {
|
||||||
let wasm = wabt::wat2wasm(
|
let wasm = wabt::wat2wasm(
|
||||||
|
@ -193,7 +238,7 @@ fn recursive_ok(b: &mut Bencher) {
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let value = instance
|
let value = instance
|
||||||
.invoke_export("call", &[RuntimeValue::I32(9999)], &mut NopExternals);
|
.invoke_export("call", &[RuntimeValue::I32(8000)], &mut NopExternals);
|
||||||
assert_matches!(value, Ok(Some(RuntimeValue::I32(0))));
|
assert_matches!(value, Ok(Some(RuntimeValue::I32(0))));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tiny-keccak = "1.4.2"
|
tiny-keccak = "1.4.2"
|
||||||
rlibc = "1.0"
|
regex = "0.2.10"
|
||||||
|
lazy_static = "1.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#![no_std]
|
|
||||||
#![feature(lang_items)]
|
|
||||||
#![feature(core_intrinsics)]
|
|
||||||
#![feature(panic_implementation)]
|
|
||||||
|
|
||||||
extern crate rlibc;
|
|
||||||
extern crate tiny_keccak;
|
extern crate tiny_keccak;
|
||||||
|
extern crate regex;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
use tiny_keccak::Keccak;
|
use tiny_keccak::Keccak;
|
||||||
|
|
||||||
mod rev_complement;
|
mod rev_complement;
|
||||||
|
mod regex_redux;
|
||||||
|
|
||||||
pub struct TinyKeccakTestData {
|
pub struct TinyKeccakTestData {
|
||||||
data: &'static [u8],
|
data: &'static [u8],
|
||||||
|
@ -74,7 +72,7 @@ pub extern "C" fn rev_complement_input_ptr(test_data: *mut RevComplementTestData
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rev_complement_output_ptr(test_data: *mut RevComplementTestData) -> *const u8 {
|
pub extern "C" fn rev_complement_output_ptr(test_data: *mut RevComplementTestData) -> *const u8 {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*test_data).output.as_mut_ptr()
|
(*test_data).output.as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,3 +83,40 @@ pub extern "C" fn bench_rev_complement(test_data: *mut RevComplementTestData) {
|
||||||
(*test_data).output.copy_from_slice(&result);
|
(*test_data).output.copy_from_slice(&result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RegexReduxTestData {
|
||||||
|
input: Box<[u8]>,
|
||||||
|
output: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn prepare_regex_redux(size: usize) -> *mut RegexReduxTestData {
|
||||||
|
regex_redux::prepare();
|
||||||
|
|
||||||
|
let input = vec![0; size];
|
||||||
|
let test_data = Box::new(
|
||||||
|
RegexReduxTestData {
|
||||||
|
input: input.into_boxed_slice(),
|
||||||
|
output: None,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Basically leak the pointer to the test data. This shouldn't be harmful since `prepare` is called
|
||||||
|
// only once per bench run (not for the iteration), and afterwards whole memory instance is discarded.
|
||||||
|
Box::into_raw(test_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn regex_redux_input_ptr(test_data: *mut RegexReduxTestData) -> *mut u8 {
|
||||||
|
unsafe {
|
||||||
|
(*test_data).input.as_mut_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn bench_regex_redux(test_data: *mut RegexReduxTestData) {
|
||||||
|
unsafe {
|
||||||
|
let result = regex_redux::run(&*(*test_data).input);
|
||||||
|
(*test_data).output = Some(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
//! Initially it supposed to be like [1]. However it turned out
|
||||||
|
//! that executing this code in wasmi way too slow.
|
||||||
|
//!
|
||||||
|
//! [1]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/regexredux-rust-2.html
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref REGEX: ::regex::bytes::Regex = {
|
||||||
|
::regex::bytes::Regex::new("agggtaa[cgt]|[acg]ttaccct").unwrap()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepare() {
|
||||||
|
®EX;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(seq: &[u8]) -> usize {
|
||||||
|
REGEX.find_iter(seq).count()
|
||||||
|
}
|
Loading…
Reference in New Issue