-
-
Notifications
You must be signed in to change notification settings - Fork 277
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
[Tracking issue] Querying number of bytes needed to encode a struct #539
Comments
We haven't implemented let size = bincode::serialize_size(&T, &config).unwrap();
let mut vec = vec![0u8; size];
bincode::encode_into_slice(&T, vec.as_mut_slice(), config).unwrap(); We personally have found that the above is a lot slower than simply encoding to a let mut vec = bincode::encode_to_vec(&T, config).unwrap(); But maybe there's a use case we missed? |
I was thinking of using it in an FFI call, so that I could serialize into memory owned by C. |
Would it be possible to:
Otherwise it is possible to create your own |
I'll leave this open as a tracking issue to see if other people are interested in having a method to get the encoded |
Yeah, I made my own Thanks for considering, and I'll be interested to see if anyone else wants this. |
@VictorKoenders I was also looking for serialized_size in bincode. My use case is I handle deserialization in rust open a file in python (the interface done with pyo3) and don't want to read the entire file content into a byte array. The usage I have in mind would be something along the lines of:
and on the backend i have - in bincode 1 - something like
Sure there are a number of things I could change about the approach (hard coding the size and adding a test to catch when i update the definition of (As an aside, what bincode 1 doesn't do perfectly for me either is that I don't have a dynamically sized object and would want to call |
Serializing the length of a section so that it can be skipped over in decoding. |
I think it should be documented that |
This problem is causing me headaches for years. So this is my use case: I am sending data over the network. I am sending a Header+Request. The header has to contain the serialized size of the Request+Header. My current solution is to make all structs "#[repr(packed)]" and use std::mem::size_size_of to get the serialized size. So I would like to remove "#repr(packed)" and use bincode::serialized_size, however it requires a concrete object and I would like to avoid that. Basically what I would like to have is a method that calculates the serialized size of my struct at compile time or at least without creating the object. |
This sounds somewhat useful to me as well. However I think it should be a separate trait, because for many types the serialized size is dynamic. You could have a (preferably derivable) StaticSerializedSize trait, which might depend on the encoding but not on any objects, just on the class.
… On Dec 2, 2022, at 5:24 PM, Marco Boneberger ***@***.***> wrote:
This problem is causing me headaches for years. So this is my use case:
I am sending data over the network. I am sending a Header+Request. The header has to contain the serialized size of the Request+Header.
My current solution is to make all structs "#[repr(packed)]" and use std::mem::size_size_of to get the serialized size.
However, there are some restrictions on what you can do with packed structs (rust-lang/rust#82523 <rust-lang/rust#82523>).
So I would like to remove "#repr(packed)" and use bincode::serialized_size, however it requires a concrete object and I would like to avoid that. Basically what I would like to have is a method that calculates the serialized size of my struct at compile time or at least without creating the object.
—
Reply to this email directly, view it on GitHub <#539 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AACGKXFEZEZFJZ2EMLMAY3DWLIPERANCNFSM5S67C42A>.
You are receiving this because you authored the thread.
|
My use case is that I am using a file as a database and some parts of the buffer are not being used. I want to know whether the thing I need to insert into the file should go at the end or whether I can write it over one of the unused chunks in the file. For my particular case I'd actually prefer an API that just gave me an upper bound given the type (this sounds like what @marcbone is asking for too): match bincode::max_serialized_size::<T>(bincode_config) {
Some(max_size) => { /* serializing T will always take <= max_size */ },
None => { /* there is no upper bound */ }
} This would be practically zero performance cost and good enough for my particular use but I think both |
I'll go ahead and register my interest here, as I was looking through the bincode-2 tagged issues. I have this struct ByteCounter {
count: usize,
}
impl Writer for ByteCounter {
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
self.count += bytes.len();
Ok(())
}
}
/// Count the bytes a value will occupy when encoded.
pub fn count_bytes<T: Encode>(x: &T) -> usize {
let mut counter = ByteCounter { count: 0 };
bincode::encode_into_writer(x, &mut counter, bincode_config()).unwrap();
counter.count
} in a codebase of mine because I'm talking to SQLite and don't want to create a serialized copy of an object I'm working with outside of what I write into a SQLite BLOB, and SQLite requires you to set the length of a BLOB before you start writing to it. In this case, it's about memory usage, not serialization performance. That said, it's not a big deal to me whether this specific API ends up in bincode, as I've already implemented it in user code. (Edit: That |
I think this is already resolved with SizeWriter and encode_into_writer: let mut size_writer = SizeWriter::default();
bincode::encode_into_writer(&t, &mut size_writer, config).unwrap();
println!("{:?}", size_writer.bytes_written Does this work for your use case? Then I think this issue can be closed |
Yup. I'm not actually sure how I missed that that exists 👍 |
Thanks for testing 👍 closing this |
I've noticed that v2.0 doesn't have a serialized size function. I'm a rust newbie, so I'm not going to attempt a pull request, but an implementation like this would probably suffice?
The text was updated successfully, but these errors were encountered: