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