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 
create_command() -> Command9 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 
python_fibonacci(c: &mut Criterion)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