-
Notifications
You must be signed in to change notification settings - Fork 266
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
Remove GenericArray #2857
Remove GenericArray #2857
Conversation
819bfac
to
bd9cd44
Compare
This is the serde code from the generic-array crate that I've ported over: https://github.com/fizyk20/generic-array/blob/master/src/impl_serde.rs |
28dff09
to
14e9499
Compare
3be8e37
to
26c517c
Compare
The unsafe code can be replaced with |
26c517c
to
92638a3
Compare
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.
Sorry for the long wait on this, I wanted to take time to properly test the implementation. Since serialization is simple, I setup a simple bench to see how deserialization performs:
#![feature(test)]
extern crate test;
use {
solana_signature::Signature,
std::hint::black_box,
test::Bencher
};
#[bench]
fn bench(b: &mut Bencher) {
let sig_bytes: [u8; 64] = [
01, 02, 03, 04, 05, 06, 07, 08, 09, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32,
01, 02, 03, 04, 05, 06, 07, 08, 09, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32,
];
let mut reverse_sig_bytes = sig_bytes.clone();
reverse_sig_bytes.reverse();
b.iter(|| {
for _ in 0..100_000 {
black_box(bincode::deserialize::<Signature>(&sig_bytes).unwrap());
black_box(bincode::deserialize::<Signature>(&reverse_sig_bytes).unwrap());
}
});
}
This PR does exactly the same performance as master:
test bench ... bench: 316,893.35 ns/iter (+/- 665.45)
I also lifted the exact implementation from serde for its arrays, and it got way worse:
test bench ... bench: 27,246,217.40 ns/iter (+/- 765,600.49)
I also tried serde_big_array:
test bench ... bench: 316,795.35 ns/iter (+/- 523.79)
Considering it provides the same performance as all the hand-rolled code, how about we use serde-big-array? I tested build times with this PR and with serde-big-array, and I noticed 0 impact on my machine.
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.
Looks great, thanks!
automerge label removed due to a CI failure |
This branches off #2054 so that needs to be merged first
Problem
generic-array
is an annoying dependency that is quite avoidable. We can avoid it by hand rolling the serde impls forSignature
, or by using theserde_with
orserde-big-array
crates.This PR hand rolls the serde impls by closely mimicking what generic-array does (but without the generic stuff). The advantage of this approach is that we should have the same behaviour and performance as before. The disadvantage of this approach is I cargo culted it somewhat so it would be good for someone to look over the unsafe code.
It's possible that serde_with or serde-big-array are better solutions but I haven't investigated the performance or if they differ in any edge cases. I did try
serde_bytes
and saw that it serialized differently when usingshort_vec
, so the serialization is not trivial.Summary of Changes
GenericArray<u8, U64>
with[u8; 64]
generic-array