tokio-rs / bytes

Utilities for working with bytes
MIT License
1.86k stars 278 forks source link

Is the conversion from bytes to Vec<u8> O(1) #711

Open cBournhonesque opened 3 months ago

cBournhonesque commented 3 months ago

Is the conversion from bytes to Vec O(1) if the underlying memory is already contiguous and the ref count is 1?

Or do we still have new allocations and copying?

I looked at https://github.com/tokio-rs/bytes/pull/547, it seems to suggest that it indeed is O(1) but the docs say

Copies self into a new Vec.

Darksonn commented 3 months ago

Beyond requiring that the refcount is 1. It is also required that the data is stored at the beginning of the underlying allocation. Otherwise, it will need to copy the data backwards.

https://github.com/tokio-rs/bytes/blob/fa1daac3ae1dcb07dffe3a41a041dffd6edf177b/src/bytes.rs#L1215-L1218

if the underlying memory is already contiguous

The memory in a Bytes is always contiguous.

cBournhonesque commented 3 months ago

So in all cases there is a copy operation, but if the refcount is not 1 (or data not stored at the beginning of the underlying allocation) there is also an allocation?

Should I make a PR to update the docstring?

Darksonn commented 3 months ago

If the refcount is one, it's just a copy within the existing buffer. There is no allocation. Allocations only happen if the refcount is at least 2.

You're very welcome to send a PR.

cBournhonesque commented 3 months ago

I tried to find where the docs for https://docs.rs/bytes/latest/bytes/struct.Bytes.html#method.to_vec are defined but I couldn't find them

Darksonn commented 3 months ago

Oh, that method will certainly copy the bytes unconditionally. It's defined on the standard library slice type, and Bytes does not (and can't) override it.

The conversion that we provide is here:

https://github.com/tokio-rs/bytes/blob/fa1daac3ae1dcb07dffe3a41a041dffd6edf177b/src/bytes.rs#L943-L948

It's called using the From trait rather than a method called to_vec.