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}