Last active
April 4, 2018 02:51
-
-
Save siddontang/aaef1f1ca4a4e86c2d6c0f6afe0364eb to your computer and use it in GitHub Desktop.
This file contains hidden or 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; | |
extern crate parking_lot; | |
extern crate crossbeam_channel; | |
use std::collections::VecDeque; | |
use test::Bencher; | |
use std::sync::mpsc::{channel, sync_channel}; | |
use std::thread; | |
use std::sync::{Arc, Mutex, Condvar}; | |
#[bench] | |
fn bench_thread_channel(b: &mut Bencher) { | |
let (tx, rx) = channel(); | |
let t = thread::spawn(move || { | |
let mut n2: usize = 0; | |
loop { | |
let n = rx.recv().unwrap(); | |
if n == 0 { | |
return n2; | |
} | |
n2 += 1; | |
} | |
}); | |
let mut n1 = 0; | |
b.iter(|| { | |
n1 += 1; | |
tx.send(1).unwrap() | |
}); | |
tx.send(0).unwrap(); | |
let n2 = t.join().unwrap(); | |
assert_eq!(n1, n2); | |
} | |
#[bench] | |
fn bench_thread_sync_channel(b: &mut Bencher) { | |
let (tx, rx) = sync_channel(100000); | |
let t = thread::spawn(move || { | |
let mut n2: usize = 0; | |
loop { | |
let n = rx.recv().unwrap(); | |
if n == 0 { | |
return n2; | |
} | |
n2 += 1; | |
} | |
}); | |
let mut n1 = 0; | |
b.iter(|| { | |
n1 += 1; | |
tx.send(1).unwrap() | |
}); | |
tx.send(0).unwrap(); | |
let n2 = t.join().unwrap(); | |
assert_eq!(n1, n2); | |
} | |
#[bench] | |
fn bench_thread_condvar(b: &mut Bencher) { | |
let v = VecDeque::with_capacity(1000); | |
let pair = Arc::new((Mutex::new(v), Condvar::new())); | |
let pair2 = pair.clone(); | |
let t = thread::spawn(move || { | |
let &(ref lock, ref cvar) = &*pair; | |
let mut started = lock.lock().unwrap(); | |
let mut n2: usize = 0; | |
loop { | |
match started.pop_front() { | |
Some(0) => return n2, | |
Some(_) => n2 += 1, | |
None => started = cvar.wait(started).unwrap(), | |
} | |
} | |
}); | |
let mut n1 = 0; | |
b.iter(|| { | |
n1 += 1; | |
{ | |
let &(ref lock, ref cvar) = &*pair2; | |
let mut started = lock.lock().unwrap(); | |
started.push_back(1); | |
cvar.notify_one(); | |
} | |
}); | |
{ | |
let &(ref lock, ref cvar) = &*pair2; | |
let mut started = lock.lock().unwrap(); | |
started.push_back(0); | |
cvar.notify_one(); | |
} | |
let n2 = t.join().unwrap(); | |
assert_eq!(n1, n2); | |
} | |
#[bench] | |
fn bench_thread_parkinglot(b: &mut Bencher) { | |
let v = VecDeque::with_capacity(1000); | |
let pair = Arc::new((parking_lot::Mutex::new(v), parking_lot::Condvar::new())); | |
let pair2 = pair.clone(); | |
let t = thread::spawn(move || { | |
let &(ref lock, ref cvar) = &*pair; | |
let mut started = lock.lock(); | |
let mut n2: usize = 0; | |
loop { | |
match started.pop_front() { | |
Some(0) => return n2, | |
Some(_) => n2 += 1, | |
None => cvar.wait(&mut started), | |
} | |
} | |
}); | |
let mut n1 = 0; | |
b.iter(|| { | |
n1 += 1; | |
{ | |
let &(ref lock, ref cvar) = &*pair2; | |
let mut started = lock.lock(); | |
started.push_back(1); | |
cvar.notify_one(); | |
} | |
}); | |
{ | |
let &(ref lock, ref cvar) = &*pair2; | |
let mut started = lock.lock(); | |
started.push_back(0); | |
cvar.notify_one(); | |
} | |
let n2 = t.join().unwrap(); | |
assert_eq!(n1, n2); | |
} | |
#[bench] | |
fn bench_thread_crossbeam(b: &mut Bencher) { | |
let (tx, rx) = crossbeam_channel::unbounded(); | |
let t = thread::spawn(move || { | |
let mut n2: usize = 0; | |
loop { | |
let n = rx.recv().unwrap(); | |
if n == 0 { | |
return n2; | |
} | |
n2 += 1; | |
} | |
}); | |
let mut n1 = 0; | |
b.iter(|| { | |
n1 += 1; | |
tx.send(1).unwrap() | |
}); | |
tx.send(0).unwrap(); | |
let n2 = t.join().unwrap(); | |
assert_eq!(n1, n2); | |
} |
Author
siddontang
commented
Mar 16, 2018
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment