Last active
March 3, 2019 11:13
-
-
Save Kroisse/8d7fb464dbb74723be5e2e7b2d19b07f to your computer and use it in GitHub Desktop.
Static Dispatch vs Dynamic Dispatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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