Skip to content

Commit b129d93

Browse files
perf(value): optimize Display implementation for Value enum
Optimized the `std::fmt::Display` trait implementation for the `Value` enum to reduce memory allocations and unnecessary clones. Replaced `format!()` and intermediate `String::from()` buffers with direct writes to the `std::fmt::Formatter` via `write!()`. Removed redundant `.clone()` calls during formatting to avoid unnecessary heap allocations. Trailing delimiters correctly emulate the original format output. Co-authored-by: ashyanSpada <22587148+ashyanSpada@users.noreply.github.com>
1 parent 9a4a6cc commit b129d93

2 files changed

Lines changed: 13 additions & 12 deletions

File tree

.jules/bolt.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99
## 2024-05-26 - Optimize decimal conversion in Value
1010
**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).
1111
**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.
12+
13+
## 2024-05-27 - Avoid intermediate strings and clones in std::fmt::Display
14+
**Learning:** For `std::fmt::Display` implementations involving collections (like Lists or Maps), building an intermediate `String` via `format!()` and `push_str()` before writing it causes unnecessary heap allocations and redundant data cloning.
15+
**Action:** Write directly to the `std::fmt::Formatter` using `write!(f, ...)` to stream characters without allocating extra memory, and remove unnecessary `.clone()` calls during formatting.

src/value.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,22 @@ pub enum Value {
1717
impl fmt::Display for Value {
1818
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1919
match self {
20-
Self::String(val) => write!(f, "value string: {}", val.clone()),
21-
Self::Number(val) => write!(f, "value number: {}", val.clone()),
22-
Self::Bool(val) => write!(f, "value bool: {}", val.clone()),
20+
Self::String(val) => write!(f, "value string: {}", val),
21+
Self::Number(val) => write!(f, "value number: {}", val),
22+
Self::Bool(val) => write!(f, "value bool: {}", val),
2323
Self::List(values) => {
24-
let mut s = String::from("[");
24+
write!(f, "value list: [")?;
2525
for value in values {
26-
s.push_str(format!("{},", value.clone()).as_str());
26+
write!(f, "{},", value)?;
2727
}
28-
s.push_str("]");
29-
write!(f, "value list: {}", s)
28+
write!(f, "]")
3029
}
3130
Self::Map(m) => {
32-
let mut s = String::from("{");
31+
write!(f, "value map: {{")?;
3332
for (k, v) in m {
34-
s.push_str(format!("key: {},", k.clone()).as_str());
35-
s.push_str(format!("value: {}; ", v.clone()).as_str());
33+
write!(f, "key: {},value: {}; ", k, v)?;
3634
}
37-
s.push_str("}");
38-
write!(f, "value map: {}", s)
35+
write!(f, "}}")
3936
}
4037
Self::None => write!(f, "None"),
4138
}

0 commit comments

Comments
 (0)