Skip to content

Instantly share code, notes, and snippets.

@rbran
Created October 8, 2015 18:57
Show Gist options
  • Save rbran/c16541d7c396dc874510 to your computer and use it in GitHub Desktop.
Save rbran/c16541d7c396dc874510 to your computer and use it in GitHub Desktop.
Simple Bench to test dynamic and static dispatching on Rust.
use std::env;
use std::io;
use std::option::Option;
struct StructTest {
any_value: i32
}
trait TraitDynamicDispatch {
fn call(&mut self, func: &mut FnMut(i32) -> i32) -> Option<io::Result<()>>;
}
impl TraitDynamicDispatch for StructTest {
fn call(&mut self, func: &mut FnMut(i32) -> i32) -> Option<io::Result<()>> {
//just do some calc
let mut sum: i32 = 0;
for i in 1..3 {
sum += func(i);
}
if sum != self.any_value {
Some(Ok(()))
} else {
None
}
}
}
trait TraitFunctionPointer {
fn call(&mut self, func: fn(i32) -> i32) -> Option<io::Result<()>>;
}
impl TraitFunctionPointer for StructTest {
fn call(&mut self, func: fn(i32) -> i32) -> Option<io::Result<()>> {
//just do some calc
let mut sum: i32 = 0;
for i in 1..3 {
sum += func(i);
}
if sum != self.any_value {
Some(Ok(()))
} else {
None
}
}
}
impl StructTest {
fn call_static_dispatch<F>(&mut self, func: &mut F) -> Option<io::Result<()>>
where F: FnMut(i32) -> i32 {
//just do some calc
let mut sum: i32 = 0;
for i in 1..3 {
sum += func(i);
}
if sum != self.any_value {
Some(Ok(()))
} else {
None
}
}
fn call_function_pointer(&mut self, func: fn(i32) -> i32) -> Option<io::Result<()>> {
//just do some calc
let mut sum: i32 = 0;
for i in 1..3 {
sum += func(i);
}
if sum != self.any_value {
Some(Ok(()))
} else {
None
}
}
}
fn main (){
fn func(x: i32) -> i32 { x * 3 };
let mut clos = |x: i32| -> i32 { x * 3 };
match env::args().nth(1) {
Some(s_arg) =>
match s_arg.as_ref() {
"tdyn" => {
let mut trait_dynamic_dispatch : &mut TraitDynamicDispatch = &mut StructTest { any_value: 0};
for _ in 1..30000000 {
trait_dynamic_dispatch.call(&mut clos);
}
},
"tfun" => {
let mut trait_function_pointer : &mut TraitFunctionPointer = &mut StructTest { any_value: 0};
for _ in 1..30000000 {
trait_function_pointer.call(func);
}
},
"ssta" => {
let mut struct_static_dispatch = StructTest{ any_value: 0};
for _ in 1..30000000 {
struct_static_dispatch.call_static_dispatch(&mut clos);
}
},
"sfun" => {
let mut struct_function_pointer = StructTest{ any_value: 0};
for _ in 1..30000000 {
struct_function_pointer.call_function_pointer(func);
}
},
_ => panic!()
}
,
None => panic!()
}
}
/*
for type in "tdyn" "tfun" "ssta" "sfun"; do :(
for i in $(seq 5); do
time ./bench ${type}
done
done
Trait Dynamic Dispatch
./bench tdyn 3.38s user 0.00s system 100% cpu 3.386 total
./bench tdyn 3.38s user 0.01s system 100% cpu 3.389 total
./bench tdyn 3.39s user 0.00s system 100% cpu 3.391 total
./bench tdyn 3.39s user 0.01s system 100% cpu 3.399 total
./bench tdyn 3.39s user 0.00s system 99% cpu 3.390 total
Trait Function Pointer
./bench tfun 3.27s user 0.00s system 100% cpu 3.276 total
./bench tfun 3.26s user 0.00s system 100% cpu 3.259 total
./bench tfun 3.26s user 0.01s system 100% cpu 3.266 total
./bench tfun 3.27s user 0.00s system 100% cpu 3.272 total
./bench tfun 3.25s user 0.00s system 100% cpu 3.254 total
Struct Static Dispatch
./bench ssta 3.31s user 0.00s system 100% cpu 3.307 total
./bench ssta 3.30s user 0.01s system 100% cpu 3.303 total
./bench ssta 3.30s user 0.00s system 100% cpu 3.294 total
./bench ssta 3.32s user 0.00s system 100% cpu 3.324 total
./bench ssta 3.30s user 0.01s system 100% cpu 3.310 total
Struct Function Pointer
./bench sfun 3.27s user 0.00s system 100% cpu 3.267 total
./bench sfun 3.27s user 0.00s system 100% cpu 3.269 total
./bench sfun 3.29s user 0.00s system 100% cpu 3.286 total
./bench sfun 3.27s user 0.00s system 100% cpu 3.270 total
./bench sfun 3.27s user 0.00s system 100% cpu 3.269 total
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment