benchmark/
benchmark.rs

1use std::{
2    io::Cursor,
3    time::{Duration, Instant},
4};
5
6use midi_toolkit::{
7    events::Event,
8    io::{MIDIFile, MIDIWriter},
9    pipe,
10    sequence::{event::merge_events_array, to_vec, to_vec_result, unwrap_items, wrap_ok},
11};
12
13fn do_run<T: Fn()>(name: &str, repeats: i32, run: T) {
14    let mut times = Vec::new();
15    for _ in 0..repeats {
16        let start = Instant::now();
17        run();
18        times.push(start.elapsed());
19    }
20
21    let mean = times.iter().map(|t| t.as_secs_f64()).sum::<f64>() / repeats as f64;
22
23    println!(
24        "Repeats: {}   \tMin: {:?}   \tMax: {:?}   \tAvg: {:?}   \tName: {}",
25        repeats,
26        times.iter().min().unwrap(),
27        times.iter().max().unwrap(),
28        Duration::from_secs_f64(mean),
29        name
30    );
31}
32
33fn main() {
34    let filename = "D:/Midis/Ra Ra Rasputin Ultimate Black MIDI Final.mid";
35    let repeats = 4;
36
37    println!("Opening midi...");
38    let file = MIDIFile::open(filename, None).unwrap();
39
40    println!("Tracks: {}", file.track_count());
41
42    let loaded_tracks = to_vec(file.iter_all_tracks().map(|t| to_vec_result(t).unwrap()));
43
44    let mut nc: u64 = 0;
45    for track in loaded_tracks.iter() {
46        for e in track {
47            if let Event::NoteOn(_) = **e {
48                nc += 1
49            }
50        }
51    }
52    println!("Note count: {nc}");
53
54    do_run("Parse all tracks individually", repeats, || {
55        for track in file.iter_all_tracks() {
56            for _ in pipe!(track) {}
57        }
58    });
59    do_run("Merge all tracks together while parsing", repeats, || {
60        let merged = pipe!(file.iter_all_tracks()|>to_vec()|>merge_events_array());
61        for _ in merged {}
62    });
63    do_run("Clone all events", repeats, || {
64        let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
65        for track in iters {
66            for _ in track {}
67        }
68    });
69    do_run(
70        "Clone all events, then wrap and unwrap them in Result",
71        repeats,
72        || {
73            let iters = pipe!(loaded_tracks
74                .iter()
75                .map(|t| pipe!(t.iter().cloned()|>wrap_ok()|>unwrap_items())));
76            for track in iters {
77                for _ in track {}
78            }
79        },
80    );
81    do_run("Merge all tracks together while cloning", repeats, || {
82        let iters =
83            pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
84        let merged = pipe!(iters|>merge_events_array());
85        for _ in merged {}
86    });
87    do_run("Write each track while cloning", repeats, || {
88        let output = Cursor::new(Vec::<u8>::new());
89        let writer = MIDIWriter::new_from_stram(Box::new(output), file.ppq()).unwrap();
90
91        let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
92        for track in iters {
93            let mut track_writer = writer.open_next_track();
94            for e in track {
95                track_writer.write_event(e).unwrap();
96            }
97        }
98    });
99    do_run("Merge each track while cloning then write", repeats, || {
100        let output = Cursor::new(Vec::<u8>::new());
101        let writer = MIDIWriter::new_from_stram(Box::new(output), file.ppq()).unwrap();
102
103        let iters =
104            pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
105        let merged = pipe!(iters|>merge_events_array()|>unwrap_items());
106        let mut track_writer = writer.open_next_track();
107        for e in merged {
108            track_writer.write_event(e).unwrap();
109        }
110    });
111}