Skip to content

perf(ui/connection_table): borrow instead of clone in Location, Service, and Application cells #407

@obchain

Description

@obchain

Problem

Three cells in the per-connection-row render path allocate Strings that could instead borrow from the existing data.

1. Location column — country_display().to_string() (line 382)

let location = conn
    .geoip_info
    .as_ref()
    .map(|g| g.country_display().to_string())   // allocates "US", "DE", …
    .unwrap_or_else(|| NONE_PLACEHOLDER.to_string()); // allocates "-"
Cell::from(location)

country_display() already returns &str (borrowed from the inner country_code). The .to_string() call and the NONE_PLACEHOLDER.to_string() fallback both allocate a String only to pass it to Cell::from. Since connection_row annotates conn: &'a Connection, the borrow can live long enough.

2. Service column — service_name.clone() in service_text (line 204–207)

fn service_text(conn: &Connection, ui_state: &UIState) -> String {
    if ui_state.show_port_numbers {
        conn.remote_addr.port().to_string()
    } else {
        conn.service_name
            .clone()                                  // clones the Option<String>
            .unwrap_or_else(|| NONE_PLACEHOLDER.to_string())  // allocates fallback
    }
}

The return value is immediately passed as &str to truncate_with_ellipsis. conn.service_name is Option<String>; we can borrow the inner &str via as_deref() instead of cloning. Changing the return type to Cow<'a, str> allows:

  • Cow::Borrowed(name) when a service name is present — zero allocation
  • Cow::Borrowed(NONE_PLACEHOLDER) when absent — zero allocation
  • Cow::Owned(port.to_string()) for the port-number branch — same as before

3. Application column compact branch — sort_key().to_string() (line 439)

let app = if width >= APP_WIDTH_FULL {
    dpi.application.to_string()
} else {
    dpi.application.sort_key().to_string()  // &'static str → String → &str
};
let budget = …;
let app = truncate_with_ellipsis(&app, budget);

sort_key() returns &'static str. Computing budget first and passing sort_key() directly to truncate_with_ellipsis eliminates the intermediate String.

Fix

  • Add use std::borrow::Cow import.
  • Annotate conn: &'a Connection in connection_row so borrowed cells get the right lifetime.
  • Location cell: .map(|g| g.country_display()).unwrap_or(NONE_PLACEHOLDER)Cell::from(&str).
  • service_textCow<'a, str> with as_deref() + Cow::Borrowed.
  • Application compact branch: compute budget first, call truncate_with_ellipsis on sort_key() directly.

Impact

Per connection row per frame:

  • Location cell: −1 String allocation (borrow from GeoIpInfo or static)
  • Service cell (service-name branch): −1 String clone + −1 String allocation for the placeholder case
  • Application cell (compact branch, common case): −1 intermediate String allocation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions