openvm_prof/
instruction_count.rs1use std::collections::HashMap;
2
3use crate::types::MetricDb;
4
5pub fn generate_instruction_count_table(db: &MetricDb) -> String {
6 let mut markdown_output = String::new();
7
8 for (label_keys, metrics_dict) in &db.dict_by_label_types {
10 let has_opcode = label_keys.iter().any(|k| k == "opcode");
11 let has_frequency = metrics_dict
12 .values()
13 .flat_map(|metrics| metrics.iter().map(|m| m.name.clone()))
14 .any(|name| name == "frequency");
15
16 if !has_opcode || !has_frequency {
17 continue;
18 }
19
20 let mut aggregated: HashMap<(Option<String>, String), f64> = HashMap::new();
22 let group_index = label_keys.iter().position(|k| k == "group");
23 let opcode_index = label_keys.iter().position(|k| k == "opcode");
24
25 for (label_values, metrics) in metrics_dict {
26 let opcode = if let Some(idx) = opcode_index {
28 label_values.get(idx).cloned().unwrap_or_default()
29 } else {
30 continue;
31 };
32
33 let group = if let Some(idx) = group_index {
35 label_values.get(idx).cloned()
36 } else {
37 None
38 };
39
40 let frequency = metrics
42 .iter()
43 .find(|m| m.name == "frequency")
44 .map(|m| m.value)
45 .unwrap_or(0.0);
46
47 let key = (group, opcode);
49 *aggregated.entry(key).or_insert(0.0) += frequency;
50 }
51
52 let mut header_parts = Vec::new();
54 if group_index.is_some() {
55 header_parts.push("group".to_string());
56 }
57 header_parts.push("opcode".to_string());
58 header_parts.push("frequency".to_string());
59
60 let header = format!("| {} |", header_parts.join(" | "));
61 let separator = format!("| {} |", vec!["---"; header_parts.len()].join(" | "));
62
63 markdown_output.push_str(&header);
64 markdown_output.push('\n');
65 markdown_output.push_str(&separator);
66 markdown_output.push('\n');
67
68 let mut sorted_entries: Vec<_> = aggregated.into_iter().collect();
70 sorted_entries.sort_by(|(_, freq_a), (_, freq_b)| {
71 freq_b
72 .partial_cmp(freq_a)
73 .unwrap_or(std::cmp::Ordering::Equal)
74 });
75
76 for ((group, opcode), frequency) in sorted_entries {
78 let formatted_freq = MetricDb::format_number(frequency);
79 if let Some(group_val) = group {
80 markdown_output.push_str(&format!(
81 "| {} | {} | {} |\n",
82 group_val, opcode, formatted_freq
83 ));
84 } else {
85 markdown_output.push_str(&format!("| {} | {} |\n", opcode, formatted_freq));
86 }
87 }
88
89 markdown_output.push('\n');
90 break; }
92
93 markdown_output
94}