Skip to content

Instantly share code, notes, and snippets.

@siddontang
Created August 31, 2018 01:23
Show Gist options
  • Save siddontang/fecbbfbb39be306f831623b6f05f6f50 to your computer and use it in GitHub Desktop.
Save siddontang/fecbbfbb39be306f831623b6f05f6f50 to your computer and use it in GitHub Desktop.
Test how to use FnOnce instead of FnBox
#![feature(test)]
extern crate test;
use std::ops::FnOnce;
use std::sync::mpsc;
use std::thread;
pub trait FnBox {
fn call_box(self: Box<Self>);
}
impl<F: FnOnce()> FnBox for F {
fn call_box(self: Box<F>) {
(*self)()
}
}
pub type Task = Box<FnBox + Send>;
fn send_a(tx: mpsc::Sender<usize>) -> impl FnOnce(usize) -> () {
move |n| tx.send(n).unwrap()
}
fn send_b<T: FnOnce(usize) + Send + 'static>(t: T) -> Task {
let c = move || {
println!("hello FnOnce");
t(1);
};
Box::new(c)
}
fn main() {
println!("Hello, world!");
let (tx, rx) = mpsc::channel();
let a = send_a(tx);
let b = send_b(a);
thread::spawn(move || {
b.call_box();
});
let v = rx.recv().unwrap();
assert_eq!(v, 1);
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::{mpsc, Arc};
use test::Bencher;
const NUM: usize = 1_000;
#[bench]
fn bench_box(b: &mut Bencher) {
let (tx, rx) = mpsc::channel();
let rem = Arc::new(AtomicUsize::new(0));
b.iter(|| {
rem.store(NUM, SeqCst);
for _ in 0..NUM {
let rem = rem.clone();
let tx = tx.clone();
let a = move || {
if 1 == rem.fetch_sub(1, SeqCst) {
tx.send(()).unwrap();
}
};
let b = Box::new(move || {
a();
});
let c = Box::new(move || {
b();
});
c();
}
});
rx.recv().unwrap();
}
#[bench]
fn bench_fnonce(b: &mut Bencher) {
let (tx, rx) = mpsc::channel();
let rem = Arc::new(AtomicUsize::new(0));
b.iter(|| {
rem.store(NUM, SeqCst);
for _ in 0..NUM {
let rem = rem.clone();
let tx = tx.clone();
let a = move || {
if 1 == rem.fetch_sub(1, SeqCst) {
tx.send(()).unwrap();
}
};
let b = move || {
a();
};
let c = move || {
b();
};
c();
}
});
rx.recv().unwrap();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment