-
Notifications
You must be signed in to change notification settings - Fork 41
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
Make it (somehow) possible to avoid needless allocations when serialising requests (needs GAT?) #711
Comments
My solution to this (that I discussed earlier in #687) is to rewrite the pub trait Serialize {
fn serialize<'this>(&'this self, target: &mut [IoSlice<'this>]);
/// Get the number of slices that need to be available for `serialize`.
fn num_slices(&self) -> usize;
/// This function can be overrided by downstream implementors to use a fixed size array instead of a vector.
fn to_slices(&self, callback: impl FnOnce(&mut [IoSlice<'_>])) {
let mut target = vec![empty_io_slice(); self.num_slices()];
self.serialize(&mut target);
callback(&mut target);
}
}
impl Serialize for GetInputFocusRequest {
fn serialize(...) {
target[0] = &[OPCODE, 0, 0, 0].into_io_slice();
}
fn num_slices(...) {
1
}
fn to_slices(...) {
let mut target = [empty_io_slice()];
self.serialize(&mut target);
callback(&mut target);
}
} With smaller requests, it ensures that serialization is kept out of the heap entirely. With larger requests that need the heap, it ensures that only one level is needed. Is it worth it? Maybe. The bottleneck here is definitely going to be server communication. It's worth a flamegraph. That being said, it should be worth it in certain cases, such as with larger requests (e.g. |
Some things I noticed from profiling the
|
I just was looking at some code and wondered why we really need
vec!
here:All of this is static. It would e.g. possible to do something like this (however, no idea how to set the length field in a way that works for both big endian and little endian):
Of course, this return type is not compatible with everything else. Perhaps a
Cow<'static, [u8]>
could work?Also: Of course, "just because" is not good enough, so: Would there be any actual benefit to doing this?
(The original code has two allocations. The one I am talking about above is for the "actual on-the-wire bytes". There is also the two
vec!
s in the last line. The first one could also be replaced with something static, butCow<'static, [Cow<'static, [u8]]>
seems a bit ugly. The second is actually free since there are no FDs and AFAIK an emptyVec
does not allocate anything.)The text was updated successfully, but these errors were encountered: