perf: refactor to reduce memory allocations and cpu work

This commit is contained in:
Cheong Lau 2025-10-05 16:36:59 +10:00 committed by Michael Murphy
parent 0c3e3c8629
commit dd0158d8f0
24 changed files with 234 additions and 242 deletions

View file

@ -9,7 +9,6 @@ use cosmic_dbus_networkmanager::{
};
use futures_util::StreamExt;
use itertools::Itertools;
use std::collections::HashMap;
use zbus::zvariant::ObjectPath;
@ -37,7 +36,7 @@ pub async fn handle_wireless_device(
// Sort by strength and remove duplicates
let mut aps = HashMap::<String, AccessPoint>::new();
for ap in access_points {
let ssid = String::from_utf8_lossy(&ap.ssid().await?.clone()).into_owned();
let ssid = String::from_utf8_lossy(ap.ssid().await?.as_slice()).into_owned();
let wps_push = ap.flags().await?.contains(ApFlags::WPS_PBC);
let strength = ap.strength().await?;
if let Some(access_point) = aps.get(&ssid) {
@ -77,10 +76,8 @@ pub async fn handle_wireless_device(
},
);
}
let aps = aps
.into_values()
.sorted_by(|a, b| b.strength.cmp(&a.strength))
.collect();
let mut aps = aps.into_values().collect::<Vec<_>>();
aps.sort_by_key(|ap| ap.strength);
Ok(aps)
}

View file

@ -71,15 +71,7 @@ pub async fn active_connections(
}
}
info.sort_by(|a, b| {
let helper = |conn: &ActiveConnectionInfo| match conn {
ActiveConnectionInfo::Vpn { name, .. } => format!("0{name}"),
ActiveConnectionInfo::Wired { name, .. } => format!("1{name}"),
ActiveConnectionInfo::WiFi { name, .. } => format!("2{name}"),
};
helper(a).cmp(&helper(b))
});
info.sort();
Ok(info)
}
@ -107,16 +99,74 @@ pub enum ActiveConnectionInfo {
impl ActiveConnectionInfo {
pub fn name(&self) -> String {
match &self {
Self::Wired { name, .. } => name.clone(),
Self::WiFi { name, .. } => name.clone(),
Self::Vpn { name, .. } => name.clone(),
Self::Wired { name, .. } | Self::WiFi { name, .. } | Self::Vpn { name, .. } => {
name.clone()
}
}
}
pub fn hw_address(&self) -> HwAddress {
match &self {
Self::Wired { hw_address, .. } => *hw_address,
Self::WiFi { hw_address, .. } => *hw_address,
Self::Wired { hw_address, .. } | Self::WiFi { hw_address, .. } => *hw_address,
Self::Vpn { .. } => HwAddress::default(),
}
}
}
impl std::cmp::Ord for ActiveConnectionInfo {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(Self::Vpn { .. }, Self::Wired { .. } | Self::WiFi { .. })
| (Self::Wired { .. }, Self::WiFi { .. }) => std::cmp::Ordering::Greater,
(Self::WiFi { .. }, Self::Wired { .. } | Self::Vpn { .. })
| (Self::Wired { .. }, Self::Vpn { .. }) => std::cmp::Ordering::Less,
(Self::Vpn { name: n1, .. }, Self::Vpn { name: n2, .. })
| (Self::Wired { name: n1, .. }, Self::Wired { name: n2, .. })
| (Self::WiFi { name: n1, .. }, Self::WiFi { name: n2, .. }) => n1.cmp(n2),
}
}
}
impl std::cmp::Eq for ActiveConnectionInfo {}
impl std::cmp::PartialOrd for ActiveConnectionInfo {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl std::cmp::PartialEq for ActiveConnectionInfo {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(
Self::Wired {
name: n1,
hw_address: a1,
..
},
Self::Wired {
name: n2,
hw_address: a2,
..
},
)
| (
Self::WiFi {
name: n1,
hw_address: a1,
..
},
Self::WiFi {
name: n2,
hw_address: a2,
..
},
) => n1 == n2 && a1 == a2,
(Self::Vpn { name: n1, .. }, Self::Vpn { name: n2, .. }) => n1 == n2,
_ => false,
}
}
}

View file

@ -263,10 +263,9 @@ async fn start_listening(
let settings = c.get_settings().await.ok().unwrap_or_default();
let s = Settings::new(settings);
if s.wifi
.clone()
.and_then(|w| w.ssid)
.and_then(|ssid| String::from_utf8(ssid).ok())
.is_some_and(|s| s == ssid)
.as_ref()
.and_then(|w| w.ssid.as_deref())
.is_some_and(|s| std::str::from_utf8(s).is_ok_and(|s| s == ssid))
{
// todo most likely we can here forget ssid from wrong hw_address
_ = c.delete().await;
@ -429,14 +428,7 @@ impl NetworkManagerState {
)
.await
.unwrap_or_default();
active_conns.sort_by(|a, b| {
let helper = |conn: &ActiveConnectionInfo| match conn {
ActiveConnectionInfo::Vpn { name, .. } => format!("0{name}"),
ActiveConnectionInfo::Wired { name, .. } => format!("1{name}"),
ActiveConnectionInfo::WiFi { name, .. } => format!("2{name}"),
};
helper(a).cmp(&helper(b))
});
active_conns.sort();
let devices = network_manager.devices().await.ok().unwrap_or_default();
let wireless_access_point_futures: Vec<_> = devices
.into_iter()
@ -483,7 +475,7 @@ impl NetworkManagerState {
})
.cloned()
.collect();
wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength));
wireless_access_points.sort_by_key(|ap| ap.strength);
self_.wireless_access_points = wireless_access_points;
for ap in &self_.wireless_access_points {
tracing::info!(
@ -519,11 +511,11 @@ impl NetworkManagerState {
let nm = NetworkManager::new(conn).await?;
for c in nm.active_connections().await.unwrap_or_default() {
if self
.wireless_access_points
.iter()
.any(|w| Ok(Some(w.ssid.clone())) == c.cached_id() && w.hw_address == hw_address)
{
if self.wireless_access_points.iter().any(|w| {
c.cached_id()
.is_ok_and(|opt| opt.is_some_and(|id| id == w.ssid))
&& w.hw_address == hw_address
}) {
_ = nm.deactivate_connection(&c).await;
}
}
@ -556,7 +548,7 @@ impl NetworkManagerState {
HashMap::from([
("identity", Value::Str(identity.into())),
// most common default
("eap", Value::Array(vec!["peap"].into())),
("eap", Value::Array(["peap"].as_slice().into())),
// most common default
("phase2-auth", Value::Str("mschapv2".into())),
("password", Value::Str(password.unwrap_or("").into())),
@ -605,16 +597,13 @@ impl NetworkManagerState {
let s = Settings::new(settings);
// todo try to add hw_address comparing here if it changes anything
if let Some(cur_ssid) = s
.wifi
.clone()
.and_then(|w| w.ssid)
.and_then(|ssid| String::from_utf8(ssid).ok())
if s.wifi
.as_ref()
.and_then(|w| w.ssid.as_deref())
.is_some_and(|s| std::str::from_utf8(s).is_ok_and(|cur_ssid| cur_ssid == ssid))
{
if cur_ssid == ssid {
known_conn = Some(c);
break;
}
known_conn = Some(c);
break;
}
}