Skip to content
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

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

Open
cBournhonesque opened this issue Jun 4, 2024 · 5 comments
Open

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

cBournhonesque opened this issue Jun 4, 2024 · 5 comments

Comments

@cBournhonesque
Copy link

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 #547, it seems to suggest that it indeed is O(1) but the docs say

Copies self into a new Vec.

@Darksonn
Copy link
Contributor

Darksonn commented Jun 4, 2024

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.

bytes/src/bytes.rs

Lines 1215 to 1218 in fa1daac

// Copy back buffer
ptr::copy(ptr, buf, len);
Vec::from_raw_parts(buf, len, cap)

if the underlying memory is already contiguous

The memory in a Bytes is always contiguous.

@cBournhonesque
Copy link
Author

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
Copy link
Contributor

Darksonn commented Jun 4, 2024

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
Copy link
Author

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
Copy link
Contributor

Darksonn commented Jun 5, 2024

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:

bytes/src/bytes.rs

Lines 943 to 948 in fa1daac

impl From<Bytes> for Vec<u8> {
fn from(bytes: Bytes) -> Vec<u8> {
let bytes = ManuallyDrop::new(bytes);
unsafe { (bytes.vtable.to_vec)(&bytes.data, bytes.ptr, bytes.len) }
}
}

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants