From 981374e3cec02e167b6a991a454f3e30aa6d2e26 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 21:31:28 +0000 Subject: [PATCH] Optimize fmt::Display for Value collections Replaced inefficient `String::from`, `format!`, and `.push_str()` logic with direct formatting writes `write!(f, ...)` to the supplied formatter inside loops for `Value::List` and `Value::Map` to avoid repeated and unnecessary heap allocations. Also removed unnecessary `.clone()` calls. Co-authored-by: ashyanSpada <22587148+ashyanSpada@users.noreply.github.com> --- .jules/bolt.md | 4 ++++ src/value.rs | 21 +++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 1878ef8..d3c2f53 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -9,3 +9,7 @@ ## 2024-05-26 - Optimize decimal conversion in Value **Learning:** `rust_decimal::Decimal` allows efficient and direct conversion to basic types like `i64` and `f64` via `to_i64` and `to_f64` using the `rust_decimal::prelude::ToPrimitive` trait. Converting to string and then parsing `val.to_string().parse()` is an anti-pattern as it incurs heap allocation overhead, which is bad for performance. When doing integer conversions from `Decimal`, it's critical to check `val.scale() == 0` first to maintain behavioral parity with string parsing (which would reject floats). **Action:** Always favor direct conversion traits like `rust_decimal::prelude::ToPrimitive` methods over stringification when converting `Decimal` values to native numeric types. Keep edge cases like `scale()` properties in mind when changing conversion methods. + +## 2024-05-27 - Optimize Display implementations for collections +**Learning:** `fmt::Display` implementations involving collections (like Lists or Maps) can be highly inefficient if they build intermediate `String`s via `format!()` and `push_str()` inside loops. This causes unnecessary heap allocations. +**Action:** Always write directly to the `fmt::Formatter` inside a loop using `write!(f, ...)` to minimize heap allocations and improve formatting performance. diff --git a/src/value.rs b/src/value.rs index d1b9133..025496c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -17,25 +17,22 @@ pub enum Value { impl fmt::Display for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::String(val) => write!(f, "value string: {}", val.clone()), - Self::Number(val) => write!(f, "value number: {}", val.clone()), - Self::Bool(val) => write!(f, "value bool: {}", val.clone()), + Self::String(val) => write!(f, "value string: {}", val), + Self::Number(val) => write!(f, "value number: {}", val), + Self::Bool(val) => write!(f, "value bool: {}", val), Self::List(values) => { - let mut s = String::from("["); + write!(f, "value list: [")?; for value in values { - s.push_str(format!("{},", value.clone()).as_str()); + write!(f, "{},", value)?; } - s.push_str("]"); - write!(f, "value list: {}", s) + write!(f, "]") } Self::Map(m) => { - let mut s = String::from("{"); + write!(f, "value map: {{")?; for (k, v) in m { - s.push_str(format!("key: {},", k.clone()).as_str()); - s.push_str(format!("value: {}; ", v.clone()).as_str()); + write!(f, "key: {},value: {}; ", k, v)?; } - s.push_str("}"); - write!(f, "value map: {}", s) + write!(f, "}}") } Self::None => write!(f, "None"), }