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