parse_benchmark/
parse_benchmark.rs

1use std::time::{Duration, Instant};
2
3use midi_toolkit::{
4    events::{Event, MIDIEventEnum},
5    io::MIDIFile,
6    pipe,
7    sequence::{
8        event::{cancel_tempo_events, get_channels_array_statistics, scale_event_time},
9        unwrap_items, TimeCaster,
10    },
11};
12
13fn do_run(name: &str, repeats: i32, run: impl Fn() -> u64) {
14    let mut times = Vec::new();
15    let mut note_count = 0;
16    for _ in 0..repeats {
17        let start = Instant::now();
18        note_count = run();
19        times.push(start.elapsed());
20    }
21
22    let mean = times.iter().map(|t| t.as_secs_f64()).sum::<f64>() / repeats as f64;
23
24    println!(
25        "Repeats: {}   \tMin: {:?}   \tMax: {:?}   \tAvg: {:?}   \tAvg NPS: {:?}   \tName: {}",
26        repeats,
27        times.iter().min().unwrap(),
28        times.iter().max().unwrap(),
29        Duration::from_secs_f64(mean),
30        note_count as f64 / mean,
31        name
32    );
33}
34
35fn main() {
36    let filename = "D:/Midis/toilet story 3 2020 ver 3840 black with tempo.mid";
37    let repeats = 4;
38
39    println!("Opening midi...");
40    let file = MIDIFile::open(filename, None).unwrap();
41
42    println!("Tracks: {}", file.track_count());
43
44    // Make windows cache stuff
45    let tracks = file.iter_all_tracks().collect();
46    let stats = get_channels_array_statistics(tracks).unwrap();
47
48    println!("Note count: {}", stats.note_count());
49
50    do_run("Parse tracks in parallel", repeats, || {
51        let tracks = file.iter_all_tracks().collect();
52        let stats = get_channels_array_statistics(tracks).unwrap();
53        stats.note_count()
54    });
55
56    do_run("Iter event batches merged", repeats, || {
57        let ppq = file.ppq();
58        let merged = pipe!(
59            file.iter_all_track_events_merged_batches()
60            |>TimeCaster::<f64>::cast_event_delta()
61            |>cancel_tempo_events(250000)
62            |>scale_event_time(1.0 / ppq as f64)
63            |>unwrap_items()
64        );
65
66        let mut note_count = 0;
67        for batch in merged {
68            for e in batch.into_iter() {
69                if let Event::NoteOn(_) = e.as_event() {
70                    note_count += 1
71                }
72            }
73        }
74
75        note_count
76    });
77
78    // do_run("Merge all tracks together while parsing", repeats, || {
79    //     let merged = pipe!(file.iter_all_tracks()|>to_vec()|>merge_events_array());
80    //     for _ in merged {}
81    // });
82    // do_run("Clone all events", repeats, || {
83    //     let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
84    //     for track in iters {
85    //         for _ in track {}
86    //     }
87    // });
88    // do_run(
89    //     "Clone all events, then wrap and unwrap them in Result",
90    //     repeats,
91    //     || {
92    //         let iters = pipe!(loaded_tracks
93    //             .iter()
94    //             .map(|t| pipe!(t.iter().cloned()|>wrap_ok()|>unwrap_items())));
95    //         for track in iters {
96    //             for _ in track {}
97    //         }
98    //     },
99    // );
100    // do_run("Merge all tracks together while cloning", repeats, || {
101    //     let iters =
102    //         pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
103    //     let merged = pipe!(iters|>merge_events_array());
104    //     for _ in merged {}
105    // });
106    // do_run("Write each track while cloning", repeats, || {
107    //     let output = Cursor::new(Vec::<u8>::new());
108    //     let writer = MIDIWriter::new_from_stram(Box::new(output), file.ppq()).unwrap();
109
110    //     let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
111    //     for track in iters {
112    //         let mut track_writer = writer.open_next_track();
113    //         for e in track {
114    //             track_writer.write_event(e).unwrap();
115    //         }
116    //     }
117    // });
118    // do_run("Merge each track while cloning then write", repeats, || {
119    //     let output = Cursor::new(Vec::<u8>::new());
120    //     let writer = MIDIWriter::new_from_stram(Box::new(output), file.ppq()).unwrap();
121
122    //     let iters =
123    //         pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
124    //     let merged = pipe!(iters|>merge_events_array()|>unwrap_items());
125    //     let mut track_writer = writer.open_next_track();
126    //     for e in merged {
127    //         track_writer.write_event(e).unwrap();
128    //     }
129    // });
130}