From b3885f80ddc997006068b1972c5196011c40ffa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Sat, 29 Jul 2023 10:15:46 +0200 Subject: [PATCH] perf: make daemon more memory efficient Use Box instead of String in daemon. Because we don't need to change names of timers in the daemon this is way more memory efficient. --- src/daemon.rs | 42 ++++++++++++++++-------------------------- src/main.rs | 4 ++-- src/timer.rs | 4 ++-- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/daemon.rs b/src/daemon.rs index 5bba1a2..7032698 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -11,8 +11,8 @@ use std::{ #[derive(Debug, Serialize, Deserialize)] pub enum Command { - Add(String, Duration), - Remove(String), + Add(Box, Duration), + Remove(Box), List, } @@ -42,12 +42,11 @@ impl Display for Answer { #[derive(Debug, thiserror::Error, Serialize, Deserialize)] pub enum AnswerErr { #[error("Timer with name '{}' already exists", .0)] - TimerAlreadyExist(String), + TimerAlreadyExist(Box), #[error("No timer with the name '{}' exists", .0)] - NoSuchTimer(String), + NoSuchTimer(Box), } - pub struct Daemon { listener: UnixListener, timers: Vec, @@ -68,14 +67,14 @@ impl Daemon { }) } - fn has_timer(&mut self, name: &String) -> bool { - self.timers.iter().any(|other| &other.name == name) + fn has_timer(&mut self, name: &str) -> bool { + self.timers.iter().any(|other| other.name.as_ref() == name) } fn handle_command(&mut self, command: Command) -> Result { println!("Received command {:?}", command); match command { - Command::List => Ok(Answer::Timers(self.timers.to_vec())), + Command::List => Ok(Answer::Timers(self.timers.clone())), Command::Add(name, duration) => { if self.has_timer(&name) { return Err(AnswerErr::TimerAlreadyExist(name)); @@ -88,12 +87,8 @@ impl Daemon { if !self.has_timer(&name) { return Err(AnswerErr::NoSuchTimer(name)); } - self.timers = self - .timers - .iter() - .cloned() - .filter(|other| other.name != name) - .collect(); + self.timers + .retain(|other| other.name.as_ref() != name.as_ref()); Ok(Answer::Ok) } } @@ -108,18 +103,13 @@ impl Daemon { } fn check_timers(&mut self) { - self.timers = self - .timers - .iter() - .cloned() - .filter(|timer| { - let expired = timer.is_expired(); - if expired { - println!("Timer {} is expired!", timer.name); - } - !expired - }) - .collect(); + self.timers.retain(|timer| { + let expired = timer.is_expired(); + if expired { + println!("Timer {} is expired!", timer.name); + } + !expired + }); } pub fn run(&mut self) -> anyhow::Result<()> { diff --git a/src/main.rs b/src/main.rs index aa44d10..96b77f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,9 +16,9 @@ fn main() -> Result<()> { CliCommand::Add { name, duration_seconds, - } => DaemonCommand::Add(name, Duration::from_secs(duration_seconds)), + } => DaemonCommand::Add(name.into_boxed_str(), Duration::from_secs(duration_seconds)), CliCommand::List => DaemonCommand::List, - CliCommand::Remove { name } => DaemonCommand::Remove(name), + CliCommand::Remove { name } => DaemonCommand::Remove(name.into_boxed_str()), }; send_command(&args.socket, daemon_command) } diff --git a/src/timer.rs b/src/timer.rs index 262f41c..291fe5e 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -33,7 +33,7 @@ mod approx_instant { #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct Timer { - pub name: String, + pub name: Box, #[serde(with = "approx_instant")] start: Instant, duration: Duration, @@ -51,7 +51,7 @@ impl Display for Timer { } impl Timer { - pub fn new(name: String, duration: Duration) -> Timer { + pub fn new(name: Box, duration: Duration) -> Timer { Timer { name, start: Instant::now(),