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
Use NonZero* or NonNull, so that Option<Bytes> is no larger than Bytes #241
Comments
As long as you make sure that you never write a NULL there, you should be good. Did you try writing a few tests and running them in Miri? Also, notice that bytes initializes an |
I feel it'd also help if we could change |
@seanmonstar union would be nice, but we use a few bits to track the variant. I'm not sure if union would let us do that. |
The bit tricks would have to operate on one of the union variant. ( |
@SimonSapin I don't know much about Rust unions. We would need the memory layout to be well defined in that case. |
Is it the representation tricks that necessitate the |
@mzabaluev Yes. In the code link in the issue description you can see a |
@SimonSapin yes, I understand most of that, except this last part:
It actually should be always atomic with |
I mean, I’m only reading the code. You can presumably do so as well as I. |
I can't claim to be good enough to understand everything in there, and I have better uses of my work day than to read through screenfuls of pointers-as-bitfields arcana 😆 It's just on the principle, I can't see a good reason imposed by the API for these pointers to be atomic. |
@mzabaluev there is mutation that happens internally. When you create a This is done, among other reasons, to make conversions from |
I suspect this is one of the cases where an implicit dynamic optimization made to benefit one use case penalizes all other users of the crate who may not need it at all. What usage patterns channel people into starting off with Could the optimized conversions be addressed explicitly with a |
The double allocation - one for |
The problem is that buffer capacity is often allocated in multiples of page size. Inlining the metadata will break this and not play well with allocators. |
Either way, the path forward for any change would be to demonstrate it performs better than the current impl for common usage patterns. |
The allocator is supposed to properly align any |
Yep... so now a 4kb allocation takes 8kb... etc |
Does it matter how much of a 2^n allocated size is taken up by the header, as long as the rest is available for data? I did not notice any particular guarantees about the capacity growth strategy in the docs, so I assume the implementation is free to change it. |
One potential drawback with an inline shared buffer layout is reallocation of small buffers, where the overhead of copying the header to the new contiguous DST structure factors noticeably in the overall copying cost. I'd wager that smaller reserved capacities in I agree that benchmarking on typical application workloads is important. |
In master now (from #298), both |
It would be nice if
size_of::<Option<Bytes>>()
was the same assize_of::<Bytes>()
. The compiler does this if one of the fields insideBytes
/bytes::Inner
has a type that is statically known to be non-zero or non-null:&T
,Box<T>
,num::NonZeroUsize
,ptr::NonNull<T>
, …https://github.com/carllerche/bytes/blob/42b669690af1f358dd5234beb5078ebdf25b3e02/src/bytes.rs#L301-L304
I believe that
arc
is the only possible candidate without changing the data representation. It contains either a non-zero marker in its lower two bits, or a non-null pointer for theKIND_ARC
case. Other fields can be entirely zero, at least in theKIND_INLINE
case.However replacing the field with
arc: NonNull<Shared>
is not enough, since some of the accesses to it are atomic.The standard library provides
AtomicPtr
andptr::NonNull
, but notAtomicNonNullPtr
nor atomic operations on raw pointers. However, maybe we could build aAtomicNonNullPtr
type that containsUnsafeCell<NonNull<T>>
, and implements atomic operations based on unsafely casting&UnsafeCell<NonNull<T>>
to&AtomicPtr<T>
:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=811d20754131c6339802fb05d0908afe
@RalfJung I think this would be sound, but am I missing something?
The text was updated successfully, but these errors were encountered: