on my main dev machine, serde takes up 16 of the 29 seconds required to do a release build of sled. human optimizations are the most important for long-term system health, since they encourage all other optimizations. sled doesn't need very complex serialization, so this will be fairly easy to replace.
Sounds like a good plan :+1:
sled doesn't need very complex serialization, so this will be fairly easy to replace.
Any idea / proposal what serde can be replaced with?
@pmuens I replaced it with a pretty simple implementation in #902 that just uses some simple rust traits to write very little code, and it still performs on-par with serde even though now it takes half the time to compile the project!
@spacejam that's awesome! 馃憣
I was wondering if there might be a need for a more lightweight serde-like crate which only provides the most minimal boilerplate to get basic serialization working. There might be something out there already (I haven't looked) but this is more rooted in educational curiosity.
I really enjoy the implementation in serialization.rs. Do you think there's room to make this more generic? Or do we end up with a reimplementation of serde once we'd go down that path?
@pmuens yeah! @Geal has a nice crate, cookie factory that is a pretty clean and generic implementation of a simple serializer. It should be noted though that serde is really good due to the human convenience factor, and bincode used with serde is fast enough for many workloads. Once you go down the hand-written (even library-assisted) path, it's important to start spending a lot more effort on testing as well. That's why like half of the new serialization module in sled is just quickcheck tests.
There are a few key reasons why I eventually chose to remove serde after 4 years of it being a great choice:
serialized_size and serialize_into functions, but I figured I might as well address all of these issues in a single effort as well.Sorry for the wall of text, but I have a feeling I'll be referring back to this when people ask about it.
Thanks for the in-depth writeup @spacejam! 馃憤
Sorry for the wall of text
Absolutely not! It was a really insightful to read about all the (non obvious) implications an external dependency can have on the (human) performance as well as the overall DB architecture and design.
Can you elaborate a bit on how from-scratch compile times add friction to your lived experience? I feel like they mostly don't matter that much to me.
For the other points, it feels like they could be addressed to some extent by using serde but writing a custom Serializer/Deserializer. That potentially makes the API for users a little bit more idiomatic because you can still use Serialize/Deserialize for the types involved.
@djc I don't need the genericism though, it's an abstraction that doesn't help me write my functionality any faster. It would also block off a number of optimizations that can only be taken because I have information beyond the type signature of the types used in sled. Take the PageState enum for example. 2 variants, one has between 1 and 16 repeated fields, the other has 0. I can use a single byte to represent both the variant and the length for the repeated item. Generic abstractions block optimization opportunities. After 4 years of building this thing, I'm at the point where these are the optimizations that make big differences. One of the biggest problems in sled right now is that it takes too much space on disk, and there are a ton of great non-generic optimizations I can pursue to fix this.
Storage engines are all about finding generic abstractions and breaking them in the name of performance while staying on the right side of the actual correctness requirements.
I spend a lot of time compiling in fresh directories. I spend a lot of time waiting for sanitizers to build, which need to start fresh, as well as CI, which often doesn't use caches as it should. I don't want users who try out sled to feel like they just made their project a lot slower to build.
I would definitely use serde for the first 4 years all over again, but at this point the genericism stands in the way.
Makes sense, thanks for elaborating!
Most helpful comment
@pmuens yeah! @Geal has a nice crate, cookie factory that is a pretty clean and generic implementation of a simple serializer. It should be noted though that serde is really good due to the human convenience factor, and bincode used with serde is fast enough for many workloads. Once you go down the hand-written (even library-assisted) path, it's important to start spending a lot more effort on testing as well. That's why like half of the new serialization module in sled is just quickcheck tests.
There are a few key reasons why I eventually chose to remove serde after 4 years of it being a great choice:
serialized_sizeandserialize_intofunctions, but I figured I might as well address all of these issues in a single effort as well.Sorry for the wall of text, but I have a feeling I'll be referring back to this when people ask about it.