Skip to content

Commit cc72f03

Browse files
committed
Marginally reduce allocations in lightning-invoice
In aa2f6b4 we refactored `lightning-invoice` de/serialization to use the new version of `bech32`, also reducing some trivial unnecessary allocations when we did so. Here we drop a few additional allocations which came up in review.
1 parent bc1931b commit cc72f03

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

lightning-invoice/src/de.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ impl FromBase32 for PrivateRoute {
712712
return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields);
713713
}
714714

715-
let mut route_hops = Vec::<RouteHintHop>::new();
715+
let mut route_hops = Vec::with_capacity(bytes.len() / 51);
716716

717717
let mut bytes = bytes.as_slice();
718718
while !bytes.is_empty() {

lightning-invoice/src/ser.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,19 +218,20 @@ impl Display for SiPrefix {
218218
}
219219

220220
/// Encode an integer to base32, big endian, without leading zeros
221-
fn encode_int_be_base32(int: u64) -> Vec<Fe32> {
221+
fn encode_int_be_base32(int: u64) -> impl ExactSizeIterator<Item=Fe32> {
222222
let base = 32u64;
223223

224224
// (64 + 4) / 5 == 13
225-
let mut out_vec = Vec::<Fe32>::with_capacity(13);
225+
let mut out = [Fe32::Q; 13];
226+
let mut out_pos = 0;
226227
let mut rem_int = int;
227228
while rem_int != 0 {
228-
out_vec.push(Fe32::try_from((rem_int % base) as u8).expect("always <32"));
229+
out[out_pos] = Fe32::try_from((rem_int % base) as u8).expect("always <32");
230+
out_pos += 1;
229231
rem_int /= base;
230232
}
231233

232-
out_vec.reverse();
233-
out_vec
234+
out.into_iter().take(out_pos).rev()
234235
}
235236

236237
/// The length of the output of `encode_int_be_base32`.
@@ -252,7 +253,7 @@ impl Base32Iterable for PositiveTimestamp {
252253
let fes = encode_int_be_base32(self.as_unix_timestamp());
253254
debug_assert!(fes.len() <= 7, "Invalid timestamp length");
254255
let to_pad = 7 - fes.len();
255-
Box::new(core::iter::repeat(Fe32::Q).take(to_pad).chain(fes.into_iter()))
256+
Box::new(core::iter::repeat(Fe32::Q).take(to_pad).chain(fes))
256257
}
257258
}
258259

@@ -305,7 +306,7 @@ impl Base32Len for PayeePubKey {
305306

306307
impl Base32Iterable for ExpiryTime {
307308
fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> {
308-
Box::new(encode_int_be_base32(self.as_seconds()).into_iter())
309+
Box::new(encode_int_be_base32(self.as_seconds()))
309310
}
310311
}
311312

@@ -317,7 +318,7 @@ impl Base32Len for ExpiryTime {
317318

318319
impl Base32Iterable for MinFinalCltvExpiryDelta {
319320
fn fe_iter<'s>(&'s self) -> Box<dyn Iterator<Item = Fe32> + 's> {
320-
Box::new(encode_int_be_base32(self.0).into_iter())
321+
Box::new(encode_int_be_base32(self.0))
321322
}
322323
}
323324

@@ -504,6 +505,6 @@ mod test {
504505
.map(|v| Fe32::try_from(v).expect("<= 31"))
505506
.collect::<Vec<Fe32>>();
506507

507-
assert_eq!(expected_out, encode_int_be_base32(input));
508+
assert_eq!(expected_out, encode_int_be_base32(input).collect::<Vec<Fe32>>());
508509
}
509510
}

0 commit comments

Comments
 (0)