-
Notifications
You must be signed in to change notification settings - Fork 401
Store Feature
flags in line rather than on the heap by default (without increasing their size)
#3730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Store Feature
flags in line rather than on the heap by default (without increasing their size)
#3730
Conversation
I've assigned @valentinewallace as a reviewer! |
61824a3
to
03aaa63
Compare
This avoids vec doubling while doing `Features` conversions.
03aaa63
to
1160c31
Compare
In a running LDK instance we generally have a ton of `Feature`s objects flying around, including ones per channel/peer in the `NetworkGraph`, ones per channel/peer in `Channel`/`ChannelManager`, and ones inside of BOLT 11/12 Invoices. Thus, its useful to avoid unecessary allocations in them to reduce heap fragmentation. Luckily, Features generally don't have more than 15 bytes worth of flags, and because `Vec` has a `NonNull` pointer we can actually wrap a vec in a two-variant enum with zero additional space penalty. While this patch leaves actually deserializing `Features` without allocating as a future exercise, immediately releasing the allocation is much better than holding it, and `Features` constructed through repeated `set_*` calls benefit from avoiding the Vec entirely.
1160c31
to
2dd6c18
Compare
#[derive(Clone, PartialEq, Eq)] | ||
#[doc(hidden)] | ||
pub enum FeatureFlags { | ||
Held { bytes: [u8; DIRECT_ALLOC_BYTES], len: u8 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be called OnStack
/OnHeap
or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But its not necessarily on stack - its just in the object, and the object may be on heap or on stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhh. Good point, I just found the current naming a bit odd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Heap
and Direct
? I agree its odd but I don't know what's better.
🔔 1st Reminder Hey @valentinewallace! This PR has been waiting for your review. |
lightning-types/src/features.rs
Outdated
// Thus, as long as we never use more than 15 bytes for our Held variant `FeatureFlags` is the same | ||
// length as a `Vec` in memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not 16 bytes (2 usize
s as mentioned above) because we need a byte to write the type of features, or? Would be helpful to clarify that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, 16 bytes minus the length byte, I'll clarify.
No new datastructure would be complete without a dedicated fuzzer, so we add one here.
2dd6c18
to
fadb54f
Compare
In a running LDK instance we generally have a ton of
Feature
s objects flying around, including ones per channel/peer in theNetworkGraph
, ones per channel/peer inChannel
/ChannelManager
, and ones inside of BOLT 11/12 Invoices.Thus, its useful to avoid unecessary allocations in them to reduce heap fragmentation.
Luckily, Features generally don't have more than 15 bytes worth of flags, and because
Vec
has aNonNull
pointer we can actually wrap a vec in a two-variant enum with zero additional space penalty.While this patch leaves actually deserializing
Features
without allocating as a future exercise, immediately releasing the allocation is much better than holding it, andFeatures
constructed through repeatedset_*
calls benefit from avoiding the Vec entirely.