Skip to content

Commit c0107c6

Browse files
committed
Reduce on-startup heap frag due to network graph map/vec doubling
When we're reading a `NetworkGraph`, we know how many nodes/channels we are reading, there's no reason not to pre-allocate the `IndexedMap`'s inner `HashMap` and `Vec`, which we do here. This seems to reduce on-startup heap fragmentation with glibc by something like 100MiB.
1 parent 281a0ae commit c0107c6

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

lightning/src/routing/gossip.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,14 +1312,16 @@ impl<L: Deref> ReadableArgs<L> for NetworkGraph<L> where L::Target: Logger {
13121312

13131313
let chain_hash: ChainHash = Readable::read(reader)?;
13141314
let channels_count: u64 = Readable::read(reader)?;
1315-
let mut channels = IndexedMap::new();
1315+
// In Nov, 2023 there were about 15,000 nodes; we cap allocations to 1.5x that.
1316+
let mut channels = IndexedMap::with_capacity(cmp::min(channels_count as usize, 22500));
13161317
for _ in 0..channels_count {
13171318
let chan_id: u64 = Readable::read(reader)?;
13181319
let chan_info = Readable::read(reader)?;
13191320
channels.insert(chan_id, chan_info);
13201321
}
13211322
let nodes_count: u64 = Readable::read(reader)?;
1322-
let mut nodes = IndexedMap::new();
1323+
// In Nov, 2023 there were about 69K channels; we cap allocations to 1.5x that.
1324+
let mut nodes = IndexedMap::with_capacity(cmp::min(nodes_count as usize, 103500));
13231325
for _ in 0..nodes_count {
13241326
let node_id = Readable::read(reader)?;
13251327
let node_info = Readable::read(reader)?;

lightning/src/util/indexed_map.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ impl<K: Clone + Hash + Ord, V> IndexedMap<K, V> {
3939
}
4040
}
4141

42+
/// Constructs a new, empty map with the given capacity pre-allocated
43+
pub fn with_capacity(capacity: usize) -> Self {
44+
Self {
45+
map: HashMap::with_capacity(capacity),
46+
keys: Vec::with_capacity(capacity),
47+
}
48+
}
49+
4250
#[inline(always)]
4351
/// Fetches the element with the given `key`, if one exists.
4452
pub fn get(&self, key: &K) -> Option<&V> {

0 commit comments

Comments
 (0)