build: apply optimizations in release mode

TODO: Potentially highlight more performance hotspots with
`#[optimize(speed)]`.
This commit is contained in:
Erica Marigold 2025-08-27 12:46:23 +01:00
parent 8bb45bf0fb
commit 019af6bb36
Signed by: DevComp
SSH key fingerprint: SHA256:jD3oMT4WL3WHPJQbrjC3l5feNCnkv7ndW8nYaHX5wFw
7 changed files with 26 additions and 4 deletions

View file

@ -7,8 +7,23 @@ repository = "https://git.devcomp.xyz/DevComp/ssh-portfolio"
authors = ["Erica Marigold <hi@devcomp.xyz>"] authors = ["Erica Marigold <hi@devcomp.xyz>"]
build = "build.rs" build = "build.rs"
# Taken from https://github.com/microsoft/edit/blob/a3a6f5f/Cargo.toml#L20-L31
# We use `opt-level = "s"` as it significantly reduces binary size.
# We could then use the `#[optimize(speed)]` attribute for spot optimizations.
# Unfortunately, that attribute currently doesn't work on intrinsics such as memset.
[profile.release]
codegen-units = 1 # Reduces binary size by ~2%
debug = "full" # No one needs an undebuggable release binary
lto = true # Reduces binary size by ~14%
opt-level = "s" # Reduces binary size by ~25%
split-debuginfo = "packed" # Generates a separate *.dwp/*.dSYM so the binary can get stripped
strip = "symbols" # See split-debuginfo - allows us to drop the size by ~65%
[profile.dev]
opt-level = 2 # Optimize more than default, see https://github.com/RustCrypto/RSA/issues/144
incremental = true # Improves re-compile times
[features] [features]
# TODO: CLI feature
default = ["blog"] default = ["blog"]
blog = [ blog = [
# Main deps # Main deps
@ -28,9 +43,6 @@ blog = [
"dep:patch-crate" "dep:patch-crate"
] ]
[profile.dev]
opt-level = 2
[package.metadata.patch] [package.metadata.patch]
crates = ["ratatui-image"] crates = ["ratatui-image"]

View file

@ -107,6 +107,7 @@ impl App {
}) })
} }
#[optimize(speed)]
pub async fn run( pub async fn run(
&mut self, &mut self,
term: Arc<Mutex<Terminal>>, term: Arc<Mutex<Terminal>>,

View file

@ -131,6 +131,7 @@ fn project_directory() -> Option<ProjectDirs> {
ProjectDirs::from("xyz", "devcomp", env!("CARGO_PKG_NAME")) ProjectDirs::from("xyz", "devcomp", env!("CARGO_PKG_NAME"))
} }
#[optimize(speed)]
fn private_key_deserialize<'de, D>(deserializer: D) -> Result<Vec<PrivateKey>, D::Error> fn private_key_deserialize<'de, D>(deserializer: D) -> Result<Vec<PrivateKey>, D::Error>
where where
D: Deserializer<'de>, { D: Deserializer<'de>, {

View file

@ -1,3 +1,5 @@
#![feature(optimize_attribute)]
use std::net::SocketAddr; use std::net::SocketAddr;
use clap::Parser as _; use clap::Parser as _;

View file

@ -32,6 +32,7 @@ impl TermWriter {
Self { session, channel, inner: CryptoVec::new() } Self { session, channel, inner: CryptoVec::new() }
} }
#[optimize(speed)]
fn flush_inner(&mut self) -> std::io::Result<()> { fn flush_inner(&mut self) -> std::io::Result<()> {
let handle = TokioHandle::current(); let handle = TokioHandle::current();
handle.block_on(async move { handle.block_on(async move {
@ -50,6 +51,7 @@ impl TermWriter {
impl Write for TermWriter { impl Write for TermWriter {
#[instrument(skip(self, buf), level = "debug")] #[instrument(skip(self, buf), level = "debug")]
#[optimize(speed)]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
tracing::trace!("Writing {} bytes into SSH terminal writer buffer", buf.len()); tracing::trace!("Writing {} bytes into SSH terminal writer buffer", buf.len());
self.inner.extend(buf); self.inner.extend(buf);
@ -57,6 +59,7 @@ impl Write for TermWriter {
} }
#[instrument(skip(self), level = "trace")] #[instrument(skip(self), level = "trace")]
#[optimize(speed)]
fn flush(&mut self) -> std::io::Result<()> { fn flush(&mut self) -> std::io::Result<()> {
tracing::trace!("Flushing SSH terminal writer buffer"); tracing::trace!("Flushing SSH terminal writer buffer");
tokio::task::block_in_place(|| self.flush_inner()) tokio::task::block_in_place(|| self.flush_inner())

View file

@ -35,6 +35,7 @@ impl Backend for SshBackend {
Ok(Size { width: self.dims.0, height: self.dims.1 }) Ok(Size { width: self.dims.0, height: self.dims.1 })
} }
#[optimize(speed)]
fn draw<'a, I>(&mut self, content: I) -> io::Result<()> fn draw<'a, I>(&mut self, content: I) -> io::Result<()>
where where
I: Iterator<Item = (u16, u16, &'a ratatui::buffer::Cell)>, { I: Iterator<Item = (u16, u16, &'a ratatui::buffer::Cell)>, {
@ -71,6 +72,7 @@ impl Backend for SshBackend {
}) })
} }
#[optimize(speed)]
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
Backend::flush(&mut self.inner) Backend::flush(&mut self.inner)
} }

View file

@ -111,6 +111,7 @@ impl Tui {
}); });
} }
#[optimize(speed)]
async fn event_loop( async fn event_loop(
status: Arc<RwLock<TuiStatus>>, status: Arc<RwLock<TuiStatus>>,
event_tx: UnboundedSender<Event>, event_tx: UnboundedSender<Event>,