growth_main/
growth_main.rs1use std::collections::BTreeMap;
17use std::io::{self, Read};
18use std::process::ExitCode;
19
20use subms::{SubMsGrowthClass, SubMsGrowthRecipe, grow, growth_to_json};
21use subms_arena_allocator::Bump;
22
23struct ArenaChurn {
24 arena: Bump,
25 rounds: usize,
26 allocs_per_round: usize,
27}
28
29impl SubMsGrowthRecipe for ArenaChurn {
30 fn name(&self) -> &str {
31 "subms-arena-allocator"
32 }
33 fn op_name(&self) -> &str {
34 "alloc"
35 }
36 fn rounds(&self) -> usize {
37 self.rounds
38 }
39 fn ops_per_round(&self) -> usize {
40 self.allocs_per_round
41 }
42 fn op(&mut self, _round: usize, i: usize) {
43 if i == 0 {
46 self.arena.reset();
47 }
48 let _ = self.arena.alloc_copy(i as u64);
49 }
50 fn memory_bytes(&mut self) -> u64 {
51 self.arena.used() as u64
54 }
55 fn live_bytes(&mut self) -> u64 {
56 self.arena.used() as u64
59 }
60 fn structures(&mut self) -> Vec<(String, u64)> {
61 vec![("live_allocs".to_string(), self.allocs_per_round as u64)]
62 }
63 fn expected(&self) -> (SubMsGrowthClass, f64) {
64 (SubMsGrowthClass::PlateauBounded, 1.5)
67 }
68}
69
70fn parse_usize(map: &BTreeMap<String, String>, key: &str, default: usize) -> usize {
71 map.get(key)
72 .and_then(|v| v.trim().parse().ok())
73 .unwrap_or(default)
74}
75
76fn main() -> ExitCode {
77 let mut raw = String::new();
78 if io::stdin().read_to_string(&mut raw).is_err() {
79 eprintln!("growth_main: failed to read stdin");
80 return ExitCode::FAILURE;
81 }
82 let mut map = BTreeMap::new();
83 for line in raw.lines() {
84 let line = line.trim();
85 if line.is_empty() || line.starts_with('#') {
86 continue;
87 }
88 if let Some((k, v)) = line.split_once('=') {
89 map.insert(k.trim().to_string(), v.trim().to_string());
90 }
91 }
92 let rounds = parse_usize(&map, "rounds", 50);
93 let allocs_per_round = parse_usize(&map, "allocs_per_round", 20_000);
94
95 let capacity = allocs_per_round * 16 + 4096;
98 let mut recipe = ArenaChurn {
99 arena: Bump::with_capacity(capacity),
100 rounds,
101 allocs_per_round,
102 };
103 let report = grow(&mut recipe, "rust");
104
105 if growth_to_json(&report, &mut io::stdout().lock()).is_err() {
106 eprintln!("growth_main: failed to write json");
107 return ExitCode::FAILURE;
108 }
109 ExitCode::SUCCESS
110}