Skip to content

Instantly share code, notes, and snippets.

@siddontang
Last active April 4, 2018 02:51
Show Gist options
  • Save siddontang/aaef1f1ca4a4e86c2d6c0f6afe0364eb to your computer and use it in GitHub Desktop.
Save siddontang/aaef1f1ca4a4e86c2d6c0f6afe0364eb to your computer and use it in GitHub Desktop.
#![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);
}
@siddontang
Copy link
Author

siddontang commented Mar 16, 2018

[dependencies]
parking_lot = {version = "0.5", features = ["nightly"]}
crossbeam-channel = "0.1"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment