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

Add From Vec<u8> for BytesMut #414

Closed
wants to merge 1 commit into from
Closed

Add From Vec<u8> for BytesMut #414

wants to merge 1 commit into from

Conversation

leshow
Copy link
Contributor

@leshow leshow commented Jul 12, 2020

This impl exists for Bytes but not BytesMut, you have to use a &[u8] which calls to_vec again when it could just use the original vec.

@taiki-e
Copy link
Member

taiki-e commented Jul 12, 2020

I think it's intentional that From<Vec<u8>> has not been provided.

bytes/src/bytes_mut.rs

Lines 735 to 742 in 7daa7fe

// For now, use a `Vec` to manage the memory for us, but we may want to
// change that in the future to some alternate allocator strategy.
//
// Thus, we don't expose an easy way to construct from a `Vec` since an
// internal change could make a simple pattern (`BytesMut::from(vec)`)
// suddenly a lot more expensive.
#[inline]
pub(crate) fn from_vec(mut vec: Vec<u8>) -> BytesMut {

@leshow
Copy link
Contributor Author

leshow commented Jul 12, 2020

Right okay. There's a From<&[u8]> impl, that already uses that method though, but does an extra allocation, how would a From<Vec<u8>> be more expensive than that? Feel free to close this if it's not wanted.

@Kobzol
Copy link

Kobzol commented Oct 16, 2020

@taiki-e If I understand it correctly, you don't want to enable From<Vec<u8>>, because although it is fast now, it may become silently slow in the future. But by doing this you anyway force people to use the slow variant From<&[u8]>, just sooner than it's required (maybe the internal representation won't even change).

Couldn't this be handled with a deprecation warning instead, if such internal representation change occurs in the future? In that way we could get a fast solution now and a warning if it slows down in the future. I'm asking because we assumed that Vec<u8> -> BytesMut is cheap in our codebase, so it would be nice to have this method as long as it is possible.

@taiki-e
Copy link
Member

taiki-e commented Oct 17, 2020

Sorry for the late response.

how would a From<Vec<u8>> be more expensive than that?

For example, if we add From<Vec<u8>> in the current implementation, the following two are equivalent:

BytesMut::from(slice.to_vec());
BytesMut::from(&slice);

However, if the implementation of BytesMut is changed, From<Vec<u8>> may be equivalent to From<&[u8]>.
As a result, the first line becomes equivalent to BytesMut::from(&slice.to_vec()), which is inefficient (to_vec called twice).

Couldn't this be handled with a deprecation warning instead, if such internal representation change occurs in the future? In that way we could get a fast solution now and a warning if it slows down in the future. I'm asking because we assumed that Vec<u8> -> BytesMut is cheap in our codebase, so it would be nice to have this method as long as it is possible.

Unfortunately, deprecation doesn't work with trait impl and its items: playground

Copy link
Member

@taiki-e taiki-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to provide an API that relies on From<Vec<u8>> being cheaper than From<&[u8]>, so I'll close this PR, but thanks for the patch @leshow!

@taiki-e taiki-e closed this Oct 17, 2020
@Kobzol
Copy link

Kobzol commented Oct 17, 2020

There could be a special method from_vec outside any From trait impl, which could be easily deprecated. But I guess that you don't want that either?

@taiki-e
Copy link
Member

taiki-e commented Oct 17, 2020

@Kobzol Even if it's deprecatable, I don't think it's preferable to add a new API that is known likely to be deprecated in the future.
(Unless it makes available functionality that is not currently available. In this case, Vec to MytesMut conversion is already available via From<&[u8]>.)

@Kobzol
Copy link

Kobzol commented Oct 17, 2020

Well it would enable a faster version of this functionality for now, and would also preserve backwards compatibility with users that were already assuming that this fast conversion exists. But I understand if you don't think that's worth it.

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

Successfully merging this pull request may close these issues.

3 participants