| 1 | use criterion::{criterion_group, Criterion}; |
| 2 | use std::{ |
| 3 | io::{BufRead, BufReader, Write}, |
| 4 | process::{Command, Stdio}, |
| 5 | str::FromStr, |
| 6 | time::Duration, |
| 7 | }; |
| 8 | |
| 9 | fn create_command() -> Command { |
| 10 | let mut command = Command::new("python3" ); |
| 11 | command |
| 12 | .arg("benches/benchmarks/external_process.py" ) |
| 13 | .arg("10" ); |
| 14 | command |
| 15 | } |
| 16 | |
| 17 | fn python_fibonacci(c: &mut Criterion) { |
| 18 | let has_python3 = Command::new("python3" ) |
| 19 | .arg("--version" ) |
| 20 | .stdout(Stdio::null()) |
| 21 | .stderr(Stdio::null()) |
| 22 | .output() |
| 23 | .is_ok(); |
| 24 | |
| 25 | if has_python3 { |
| 26 | let process = create_command() |
| 27 | .stdin(Stdio::piped()) |
| 28 | .stdout(Stdio::piped()) |
| 29 | .spawn() |
| 30 | .expect("Unable to start python process" ); |
| 31 | |
| 32 | let mut stdin = process |
| 33 | .stdin |
| 34 | .expect("Unable to get stdin for child process" ); |
| 35 | let stdout = process |
| 36 | .stdout |
| 37 | .expect("Unable to get stdout for child process" ); |
| 38 | let mut stdout = BufReader::new(stdout); |
| 39 | c.bench_function("fibonacci-python" , |b| { |
| 40 | b.iter_custom(|iters| { |
| 41 | writeln!(stdin, "{}" , iters) |
| 42 | .expect("Unable to send iteration count to child process" ); |
| 43 | let mut line = String::new(); |
| 44 | stdout |
| 45 | .read_line(&mut line) |
| 46 | .expect("Unable to read time from child process" ); |
| 47 | let nanoseconds: u64 = |
| 48 | u64::from_str(line.trim()).expect("Unable to parse time from child process" ); |
| 49 | Duration::from_nanos(nanoseconds) |
| 50 | }) |
| 51 | }); |
| 52 | |
| 53 | // Ensure that your child process terminates itself gracefully! |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | criterion_group!(benches, python_fibonacci); |
| 58 | |