Problem
In src/ui/tabs/interfaces.rs, inside the per-interface loop that runs every TUI frame, there are three small but avoidable costs:
1. Duplicate rates.get() call (lines 76 + 82)
let rx_rate_str = if let Some(rate) = rates.get(&stat.interface_name) {
format!("{}/s", format_bytes(rate.rx_bytes_per_sec))
} else {
"---".to_string()
};
let tx_rate_str = if let Some(rate) = rates.get(&stat.interface_name) {
format!("{}/s", format_bytes(rate.tx_bytes_per_sec))
} else {
"---".to_string()
};
rates is a HashMap<String, InterfaceRates>. Both lookups hash and compare the same key (stat.interface_name). A single let rate = rates.get(&stat.interface_name); binding covers both.
2. stat.interface_name.clone() (line 93)
Cell::from(stat.interface_name.clone())
stat is already borrowed (&InterfaceStats). Cell::from accepts &str via Into<Cell<'_>>, so the clone is unnecessary — stat.interface_name.as_str() suffices.
3. s.to_string() in the header closure (line 123)
let right = |s: &str| Cell::from(Line::from(s.to_string()).right_aligned());
All arguments are &'static str literals. Line::from(s) with s: &str is valid — the codebase already uses Line::from("...") throughout. The to_string() allocates a String only to construct a Line that could be built directly from the &str.
Fix
- Merge the two
rates.get() calls into one binding.
- Replace
stat.interface_name.clone() with stat.interface_name.as_str().
- Replace
Line::from(s.to_string()) with Line::from(s) in the header closure.
All three are zero-behaviour-change refactors on the hot render path.
Impact
Per-frame, per-interface-entry: −1 HashMap hash+compare, −1 String clone. Per-frame in the header: −9 String allocations (one per column label).
Problem
In
src/ui/tabs/interfaces.rs, inside the per-interface loop that runs every TUI frame, there are three small but avoidable costs:1. Duplicate
rates.get()call (lines 76 + 82)ratesis aHashMap<String, InterfaceRates>. Both lookups hash and compare the same key (stat.interface_name). A singlelet rate = rates.get(&stat.interface_name);binding covers both.2.
stat.interface_name.clone()(line 93)statis already borrowed (&InterfaceStats).Cell::fromaccepts&strviaInto<Cell<'_>>, so the clone is unnecessary —stat.interface_name.as_str()suffices.3.
s.to_string()in the header closure (line 123)All arguments are
&'static strliterals.Line::from(s)withs: &stris valid — the codebase already usesLine::from("...")throughout. Theto_string()allocates aStringonly to construct aLinethat could be built directly from the&str.Fix
rates.get()calls into one binding.stat.interface_name.clone()withstat.interface_name.as_str().Line::from(s.to_string())withLine::from(s)in the header closure.All three are zero-behaviour-change refactors on the hot render path.
Impact
Per-frame, per-interface-entry: −1 HashMap hash+compare, −1
Stringclone. Per-frame in the header: −9Stringallocations (one per column label).