Add benchmarks and stuff
commit
551b500f4e
@ -0,0 +1 @@
|
||||
/target
|
@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/benchmarks.iml" filepath="$PROJECT_DIR$/.idea/benchmarks.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,194 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
||||
[[package]]
|
||||
name = "benchmarks"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"rayon",
|
||||
"termion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"maybe-uninit",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numtoa"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
dependencies = [
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"numtoa",
|
||||
"redox_syscall",
|
||||
"redox_termios",
|
||||
]
|
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "benchmarks"
|
||||
version = "0.1.0"
|
||||
authors = ["Trivernis <trivernis@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.3.0"
|
||||
crossbeam-channel = "0.4.2"
|
||||
termion = "1.5.5"
|
@ -0,0 +1,195 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use rayon::prelude::*;
|
||||
use std::ops::{Add, Div};
|
||||
use std::time::{Duration, Instant};
|
||||
use termion::{color, style};
|
||||
|
||||
const BENCHMARK_ITERATIONS: usize = 1000;
|
||||
|
||||
pub fn main() {
|
||||
bench_function("Spawn and Stop thread", || {
|
||||
to_test::start_stop_thread();
|
||||
});
|
||||
bench_function("MPSC channel", || {
|
||||
to_test::send_mpsc_channel();
|
||||
});
|
||||
bench_function("MPMC channel", || {
|
||||
to_test::send_mpmc_channel();
|
||||
});
|
||||
bench_function("Multiply to 100", || {
|
||||
to_test::multiply_to(100);
|
||||
});
|
||||
bench_function("Largest prime", || {
|
||||
to_test::largest_prime(1000000);
|
||||
});
|
||||
bench_function("Largest prime parallel", || {
|
||||
to_test::largest_prime_par(1000000);
|
||||
})
|
||||
}
|
||||
|
||||
fn bench_function<F: Fn()>(name: &str, func: F) {
|
||||
println!(
|
||||
"\n{}{}{}{}",
|
||||
color::Fg(color::LightBlue),
|
||||
style::Bold,
|
||||
name,
|
||||
style::Reset
|
||||
);
|
||||
let (avg_duration, durations) = bench_n_times(BENCHMARK_ITERATIONS, func);
|
||||
if durations.len() > 10 {
|
||||
println!("Durations(10):\t {:?}...", &durations[0..10]);
|
||||
} else {
|
||||
println!("Durations:\t {:?}", durations);
|
||||
}
|
||||
let standard_deviation = (durations.par_iter().sum::<Duration>().as_nanos() as f64
|
||||
/ (BENCHMARK_ITERATIONS as f64 - 1f64))
|
||||
.sqrt();
|
||||
println!(
|
||||
"Average Duration: {:?} (±{:.2}ns ~ {:.1}%)",
|
||||
avg_duration,
|
||||
standard_deviation,
|
||||
(standard_deviation / avg_duration.as_nanos() as f64) * 100f64
|
||||
);
|
||||
}
|
||||
|
||||
fn bench_n_times<F: Fn()>(n: usize, func: F) -> (Duration, Vec<Duration>) {
|
||||
let mut durations: Vec<Duration> = Vec::new();
|
||||
for _ in 0..n {
|
||||
let start = Instant::now();
|
||||
func();
|
||||
durations.push(start.elapsed());
|
||||
}
|
||||
|
||||
(
|
||||
durations
|
||||
.par_iter()
|
||||
.cloned()
|
||||
.reduce_with(|a, b| a.add(b).div(2))
|
||||
.unwrap(),
|
||||
durations,
|
||||
)
|
||||
}
|
||||
|
||||
mod to_test {
|
||||
|
||||
use crossbeam_channel::unbounded;
|
||||
use rayon::prelude::*;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::thread;
|
||||
|
||||
pub fn start_stop_thread() {
|
||||
let handle = thread::spawn(|| {
|
||||
return;
|
||||
});
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
pub fn multiply_to(end: usize) -> f64 {
|
||||
let mut result = 0f64;
|
||||
for i in 2..end {
|
||||
result = (result * i as f64) / (i - 1) as f64;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn largest_prime(end: u128) -> u128 {
|
||||
let mut last_prime = 2;
|
||||
for i in (2u128..end).step_by(2) {
|
||||
let mut is_prime = true;
|
||||
for j in 2..(i as f64).sqrt().ceil() as u128 {
|
||||
if i % j == 0 {
|
||||
is_prime = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if is_prime {
|
||||
last_prime = i;
|
||||
}
|
||||
}
|
||||
|
||||
last_prime
|
||||
}
|
||||
|
||||
pub fn largest_prime_par(end: u128) -> u128 {
|
||||
(2u128..((end as f64) / 2f64).ceil() as u128)
|
||||
.into_par_iter()
|
||||
.filter(|number| {
|
||||
let num = number * 2;
|
||||
for i in 2..(num as f64).sqrt().ceil() as u128 {
|
||||
if num % i == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
* 2
|
||||
}
|
||||
|
||||
pub fn send_mpsc_channel() {
|
||||
let (rx, tx) = channel::<usize>();
|
||||
let handle = thread::spawn(move || for _ in tx {});
|
||||
for i in 0..1000 {
|
||||
rx.send(i).unwrap();
|
||||
}
|
||||
std::mem::drop(rx);
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
pub fn send_mpmc_channel() {
|
||||
let (rx, tx) = unbounded::<usize>();
|
||||
let handle = thread::spawn(move || for _ in tx {});
|
||||
for i in 0..1000 {
|
||||
rx.send(i).unwrap();
|
||||
}
|
||||
std::mem::drop(rx);
|
||||
handle.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::to_test::*;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_start_thread(b: &mut Bencher) {
|
||||
b.iter(|| start_stop_thread());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mpsc_channel(b: &mut Bencher) {
|
||||
b.iter(|| send_mpsc_channel())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mpmc_channel(b: &mut Bencher) {
|
||||
b.iter(|| send_mpmc_channel())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_multiply_to_100(b: &mut Bencher) {
|
||||
b.iter(|| multiply_to(100));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_largest_prime_functions() {
|
||||
assert_eq!(largest_prime_par(1000), largest_prime(1000))
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_largest_prime_1000000(b: &mut Bencher) {
|
||||
b.iter(|| largest_prime(1000000));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_largest_prime_1000000_par(b: &mut Bencher) {
|
||||
b.iter(|| largest_prime_par(1000000));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue