-
Notifications
You must be signed in to change notification settings - Fork 315
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Unix end-of-line convention for Rust source files
- Loading branch information
1 parent
4d50bf1
commit a0cc158
Showing
7 changed files
with
1,342 additions
and
1,342 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
#[macro_use] | ||
extern crate criterion_bencher_compat; | ||
|
||
use criterion_bencher_compat::Bencher; | ||
|
||
fn a(bench: &mut Bencher) { | ||
bench.iter(|| { | ||
(0..1000).fold(0, |x, y| x + y) | ||
}) | ||
} | ||
|
||
fn b(bench: &mut Bencher) { | ||
const N: usize = 1024; | ||
bench.iter(|| { | ||
vec![0u8; N] | ||
}); | ||
|
||
bench.bytes = N as u64; | ||
} | ||
|
||
benchmark_group!(benches, a, b); | ||
#[macro_use] | ||
extern crate criterion_bencher_compat; | ||
|
||
use criterion_bencher_compat::Bencher; | ||
|
||
fn a(bench: &mut Bencher) { | ||
bench.iter(|| { | ||
(0..1000).fold(0, |x, y| x + y) | ||
}) | ||
} | ||
|
||
fn b(bench: &mut Bencher) { | ||
const N: usize = 1024; | ||
bench.iter(|| { | ||
vec![0u8; N] | ||
}); | ||
|
||
bench.bytes = N as u64; | ||
} | ||
|
||
benchmark_group!(benches, a, b); | ||
benchmark_main!(benches); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,26 @@ | ||
use criterion::{criterion_group, Criterion, SamplingMode}; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
|
||
fn sampling_mode_tests(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("sampling_mode"); | ||
|
||
group.sampling_mode(SamplingMode::Auto); | ||
group.bench_function("Auto", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(0))) | ||
}); | ||
|
||
group.sampling_mode(SamplingMode::Linear); | ||
group.bench_function("Linear", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(0))) | ||
}); | ||
|
||
group.sampling_mode(SamplingMode::Flat); | ||
group.bench_function("Flat", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(10))) | ||
}); | ||
|
||
group.finish(); | ||
} | ||
|
||
criterion_group!(benches, sampling_mode_tests,); | ||
use criterion::{criterion_group, Criterion, SamplingMode}; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
|
||
fn sampling_mode_tests(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("sampling_mode"); | ||
|
||
group.sampling_mode(SamplingMode::Auto); | ||
group.bench_function("Auto", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(0))) | ||
}); | ||
|
||
group.sampling_mode(SamplingMode::Linear); | ||
group.bench_function("Linear", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(0))) | ||
}); | ||
|
||
group.sampling_mode(SamplingMode::Flat); | ||
group.bench_function("Flat", |bencher| { | ||
bencher.iter(|| sleep(Duration::from_millis(10))) | ||
}); | ||
|
||
group.finish(); | ||
} | ||
|
||
criterion_group!(benches, sampling_mode_tests,); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,27 @@ | ||
#![feature(custom_test_frameworks)] | ||
#![test_runner(criterion::runner)] | ||
|
||
use criterion::{Criterion, black_box}; | ||
use criterion_macro::criterion; | ||
|
||
fn fibonacci(n: u64) -> u64 { | ||
match n { | ||
0 | 1 => 1, | ||
n => fibonacci(n - 1) + fibonacci(n - 2), | ||
} | ||
} | ||
|
||
fn custom_criterion() -> Criterion { | ||
Criterion::default() | ||
.sample_size(50) | ||
} | ||
|
||
#[criterion] | ||
fn bench_simple(c: &mut Criterion) { | ||
c.bench_function("Fibonacci-Simple", |b| b.iter(|| fibonacci(black_box(10)))); | ||
} | ||
|
||
#[criterion(custom_criterion())] | ||
fn bench_custom(c: &mut Criterion) { | ||
c.bench_function("Fibonacci-Custom", |b| b.iter(|| fibonacci(black_box(20)))); | ||
#![feature(custom_test_frameworks)] | ||
#![test_runner(criterion::runner)] | ||
|
||
use criterion::{Criterion, black_box}; | ||
use criterion_macro::criterion; | ||
|
||
fn fibonacci(n: u64) -> u64 { | ||
match n { | ||
0 | 1 => 1, | ||
n => fibonacci(n - 1) + fibonacci(n - 2), | ||
} | ||
} | ||
|
||
fn custom_criterion() -> Criterion { | ||
Criterion::default() | ||
.sample_size(50) | ||
} | ||
|
||
#[criterion] | ||
fn bench_simple(c: &mut Criterion) { | ||
c.bench_function("Fibonacci-Simple", |b| b.iter(|| fibonacci(black_box(10)))); | ||
} | ||
|
||
#[criterion(custom_criterion())] | ||
fn bench_custom(c: &mut Criterion) { | ||
c.bench_function("Fibonacci-Custom", |b| b.iter(|| fibonacci(black_box(20)))); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,56 @@ | ||
extern crate proc_macro; | ||
use proc_macro::TokenStream; | ||
use proc_macro2::{Ident, TokenTree}; | ||
use quote::quote_spanned; | ||
|
||
#[proc_macro_attribute] | ||
pub fn criterion(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
let attr = proc_macro2::TokenStream::from(attr); | ||
let item = proc_macro2::TokenStream::from(item); | ||
|
||
let span = proc_macro2::Span::call_site(); | ||
|
||
let init = if stream_length(attr.clone()) != 0 { | ||
attr | ||
} | ||
else { | ||
quote_spanned!(span=> criterion::Criterion::default()) | ||
}; | ||
|
||
let function_name = find_name(item.clone()); | ||
let wrapped_name = Ident::new(&format!("criterion_wrapped_{}", function_name.to_string()), span); | ||
|
||
let output = quote_spanned!(span=> | ||
#[test_case] | ||
pub fn #wrapped_name() { | ||
#item | ||
|
||
let mut c = #init.configure_from_args(); | ||
#function_name(&mut c); | ||
} | ||
); | ||
|
||
output.into() | ||
} | ||
|
||
fn stream_length(stream: proc_macro2::TokenStream) -> usize { | ||
stream.into_iter().count() | ||
} | ||
|
||
fn find_name(stream: proc_macro2::TokenStream) -> Ident { | ||
let mut iter = stream.into_iter(); | ||
while let Some(tok) = iter.next() { | ||
if let TokenTree::Ident(ident) = tok { | ||
if ident == "fn" { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if let Some(TokenTree::Ident(name)) = iter.next() { | ||
name | ||
} | ||
else { | ||
panic!("Unable to find function name") | ||
} | ||
extern crate proc_macro; | ||
use proc_macro::TokenStream; | ||
use proc_macro2::{Ident, TokenTree}; | ||
use quote::quote_spanned; | ||
|
||
#[proc_macro_attribute] | ||
pub fn criterion(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
let attr = proc_macro2::TokenStream::from(attr); | ||
let item = proc_macro2::TokenStream::from(item); | ||
|
||
let span = proc_macro2::Span::call_site(); | ||
|
||
let init = if stream_length(attr.clone()) != 0 { | ||
attr | ||
} | ||
else { | ||
quote_spanned!(span=> criterion::Criterion::default()) | ||
}; | ||
|
||
let function_name = find_name(item.clone()); | ||
let wrapped_name = Ident::new(&format!("criterion_wrapped_{}", function_name.to_string()), span); | ||
|
||
let output = quote_spanned!(span=> | ||
#[test_case] | ||
pub fn #wrapped_name() { | ||
#item | ||
|
||
let mut c = #init.configure_from_args(); | ||
#function_name(&mut c); | ||
} | ||
); | ||
|
||
output.into() | ||
} | ||
|
||
fn stream_length(stream: proc_macro2::TokenStream) -> usize { | ||
stream.into_iter().count() | ||
} | ||
|
||
fn find_name(stream: proc_macro2::TokenStream) -> Ident { | ||
let mut iter = stream.into_iter(); | ||
while let Some(tok) = iter.next() { | ||
if let TokenTree::Ident(ident) = tok { | ||
if ident == "fn" { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if let Some(TokenTree::Ident(name)) = iter.next() { | ||
name | ||
} | ||
else { | ||
panic!("Unable to find function name") | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,66 @@ | ||
//! This module defines a trait that can be used to plug in different Futures executors into | ||
//! Criterion.rs' async benchmarking support. | ||
//! | ||
//! Implementations are provided for: | ||
//! * Tokio (implemented directly for `tokio::Runtime`) | ||
//! * Async-std | ||
//! * Smol | ||
//! * The Futures crate | ||
//! | ||
//! Please note that async benchmarks will have a small amount of measurement overhead relative | ||
//! to synchronous benchmarks. It is recommended to use synchronous benchmarks where possible, to | ||
//! improve measurement accuracy. | ||
use std::future::Future; | ||
|
||
/// Plugin trait used to allow benchmarking on multiple different async runtimes. | ||
/// | ||
/// Smol, Tokio and Async-std are supported out of the box, as is the current-thread runner from the | ||
/// Futures crate; it is recommended to use whichever runtime you use in production. | ||
pub trait AsyncExecutor { | ||
/// Spawn the given future onto this runtime and block until it's complete, returning the result. | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T; | ||
} | ||
|
||
/// Runs futures on the 'futures' crate's built-in current-thread executor | ||
#[cfg(feature = "async_futures")] | ||
pub struct FuturesExecutor; | ||
#[cfg(feature = "async_futures")] | ||
impl AsyncExecutor for FuturesExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
futures::executor::block_on(future) | ||
} | ||
} | ||
|
||
/// Runs futures on the 'smol' crate's global executor | ||
#[cfg(feature = "async_smol")] | ||
pub struct SmolExecutor; | ||
#[cfg(feature = "async_smol")] | ||
impl AsyncExecutor for SmolExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
smol::block_on(future) | ||
} | ||
} | ||
|
||
#[cfg(feature = "async_tokio")] | ||
impl AsyncExecutor for tokio::runtime::Runtime { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
self.block_on(future) | ||
} | ||
} | ||
#[cfg(feature = "async_tokio")] | ||
impl AsyncExecutor for &tokio::runtime::Runtime { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
(*self).block_on(future) | ||
} | ||
} | ||
|
||
/// Runs futures on the 'async-std' crate's global executor | ||
#[cfg(feature = "async_std")] | ||
pub struct AsyncStdExecutor; | ||
#[cfg(feature = "async_std")] | ||
impl AsyncExecutor for AsyncStdExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
async_std::task::block_on(future) | ||
} | ||
} | ||
//! This module defines a trait that can be used to plug in different Futures executors into | ||
//! Criterion.rs' async benchmarking support. | ||
//! | ||
//! Implementations are provided for: | ||
//! * Tokio (implemented directly for `tokio::Runtime`) | ||
//! * Async-std | ||
//! * Smol | ||
//! * The Futures crate | ||
//! | ||
//! Please note that async benchmarks will have a small amount of measurement overhead relative | ||
//! to synchronous benchmarks. It is recommended to use synchronous benchmarks where possible, to | ||
//! improve measurement accuracy. | ||
use std::future::Future; | ||
|
||
/// Plugin trait used to allow benchmarking on multiple different async runtimes. | ||
/// | ||
/// Smol, Tokio and Async-std are supported out of the box, as is the current-thread runner from the | ||
/// Futures crate; it is recommended to use whichever runtime you use in production. | ||
pub trait AsyncExecutor { | ||
/// Spawn the given future onto this runtime and block until it's complete, returning the result. | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T; | ||
} | ||
|
||
/// Runs futures on the 'futures' crate's built-in current-thread executor | ||
#[cfg(feature = "async_futures")] | ||
pub struct FuturesExecutor; | ||
#[cfg(feature = "async_futures")] | ||
impl AsyncExecutor for FuturesExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
futures::executor::block_on(future) | ||
} | ||
} | ||
|
||
/// Runs futures on the 'smol' crate's global executor | ||
#[cfg(feature = "async_smol")] | ||
pub struct SmolExecutor; | ||
#[cfg(feature = "async_smol")] | ||
impl AsyncExecutor for SmolExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
smol::block_on(future) | ||
} | ||
} | ||
|
||
#[cfg(feature = "async_tokio")] | ||
impl AsyncExecutor for tokio::runtime::Runtime { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
self.block_on(future) | ||
} | ||
} | ||
#[cfg(feature = "async_tokio")] | ||
impl AsyncExecutor for &tokio::runtime::Runtime { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
(*self).block_on(future) | ||
} | ||
} | ||
|
||
/// Runs futures on the 'async-std' crate's global executor | ||
#[cfg(feature = "async_std")] | ||
pub struct AsyncStdExecutor; | ||
#[cfg(feature = "async_std")] | ||
impl AsyncExecutor for AsyncStdExecutor { | ||
fn block_on<T>(&self, future: impl Future<Output = T>) -> T { | ||
async_std::task::block_on(future) | ||
} | ||
} |
Oops, something went wrong.