Skip to content

Instantly share code, notes, and snippets.

@Kroisse
Last active March 3, 2019 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kroisse/8d7fb464dbb74723be5e2e7b2d19b07f to your computer and use it in GitHub Desktop.
Save Kroisse/8d7fb464dbb74723be5e2e7b2d19b07f to your computer and use it in GitHub Desktop.
Static Dispatch vs Dynamic Dispatch
#![feature(test)]
extern crate test;
// 지극히 평범한 함수. 아래 두 함수와의 형평성을 위해 일부러 레퍼런스를 받도록 정의했습니다.
pub fn plain(t: &i64) -> i64 {
t.double()
}
// 트레이트 객체를 인자로 받는 함수.
// https://doc.rust-lang.org/book/ch17-02-trait-objects.html
pub fn trait_object(t: &dyn Double) -> i64 {
t.double()
}
// 트레이트로 타입 인자에 조건을 건 제네릭 함수.
pub fn generic<T>(t: &T) -> i64 where T: Double {
t.double()
}
// Rust 1.26 이후부터는 위의 함수를 아래처럼 줄여 쓸 수도 있습니다.
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
pub fn universal_impl_trait(t: &impl Double) -> i64 {
t.double()
}
pub trait Double {
fn double(&self) -> i64;
}
impl Double for i64 {
fn double(&self) -> i64 {
*self
}
}
#[cfg(test)]
mod bench {
use test::{Bencher, black_box};
use super::*;
const N: i64 = 10000;
#[bench]
fn bench_plain(b: &mut Bencher) {
let a: Vec<i64> = (1..=N).collect();
b.iter(|| {
let mut sum = 0;
for i in &a {
sum += plain(i);
}
black_box(sum);
});
}
#[bench]
fn bench_trait_object_borrowed(b: &mut Bencher) {
let a: Vec<i64> = (1..=N).collect();
b.iter(|| {
let mut sum = 0;
for i in &a {
sum += trait_object(i); // implicit reborrow occurs here
}
black_box(sum);
});
}
#[bench]
fn bench_trait_object_borrowed_2(b: &mut Bencher) {
let a: Vec<i64> = (1..=N).collect();
let p: Vec<&dyn Double> = a.iter().map(|i| &*i as &dyn Double).collect();
b.iter(|| {
let mut sum = 0;
for i in &p {
sum += trait_object(*i);
}
black_box(sum);
});
}
#[bench]
fn bench_trait_object_owned(b: &mut Bencher) {
let a: Vec<Box<i64>> = (1..=N).map(Box::new).collect();
b.iter(|| {
let mut sum = 0;
for i in &a {
sum += trait_object(&**i);
}
black_box(sum);
});
}
#[bench]
fn bench_generic(b: &mut Bencher) {
let a: Vec<i64> = (1..=N).collect();
b.iter(|| {
let mut sum = 0;
for i in &a {
sum += generic(i);
}
black_box(sum);
});
}
#[bench]
fn bench_universal_impl_trait(b: &mut Bencher) {
let a: Vec<i64> = (1..=N).collect();
b.iter(|| {
let mut sum = 0;
for i in &a {
sum += universal_impl_trait(i);
}
black_box(sum);
});
}
}
$ cargo bench
Compiling …… v0.1.0 (/……/……/……)
Finished release [optimized] target(s) in 4.45s
Running target/release/deps/…………
running 6 tests
test bench::bench_generic ... bench: 2,363 ns/iter (+/- 2,325)
test bench::bench_plain ... bench: 2,658 ns/iter (+/- 1,556)
test bench::bench_trait_object_borrowed ... bench: 21,093 ns/iter (+/- 19,475)
test bench::bench_trait_object_borrowed_2 ... bench: 25,183 ns/iter (+/- 13,294)
test bench::bench_trait_object_owned ... bench: 17,931 ns/iter (+/- 12,724)
test bench::bench_universal_impl_trait ... bench: 2,258 ns/iter (+/- 1,042)
test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out
running 6 tests
test bench::bench_generic ... bench: 2,443 ns/iter (+/- 2,948)
test bench::bench_plain ... bench: 2,221 ns/iter (+/- 1,221)
test bench::bench_trait_object_borrowed ... bench: 21,436 ns/iter (+/- 18,166)
test bench::bench_trait_object_borrowed_2 ... bench: 24,242 ns/iter (+/- 16,131)
test bench::bench_trait_object_owned ... bench: 16,996 ns/iter (+/- 4,563)
test bench::bench_universal_impl_trait ... bench: 2,223 ns/iter (+/- 1,232)
test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out
running 6 tests
test bench::bench_generic ... bench: 2,352 ns/iter (+/- 656)
test bench::bench_plain ... bench: 2,540 ns/iter (+/- 14,684)
test bench::bench_trait_object_borrowed ... bench: 21,055 ns/iter (+/- 12,510)
test bench::bench_trait_object_borrowed_2 ... bench: 25,084 ns/iter (+/- 9,762)
test bench::bench_trait_object_owned ... bench: 16,135 ns/iter (+/- 5,920)
test bench::bench_universal_impl_trait ... bench: 2,427 ns/iter (+/- 1,112)
test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment