-
Notifications
You must be signed in to change notification settings - Fork 960
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 Arc<Vec<u8>> to replace Bytes in PeerId #1865
Conversation
From https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type (emphasis mine):
See also rust-lang/rust-clippy#5812. |
For the reason mentioned by Roman above, we silence the warning in our CI: rust-libp2p/.github/workflows/ci.yml Line 146 in dae07b0
|
Well this affects all downstream users too, and it's not clear why using |
The Bytes in PeerId is converted from Vec, I think using Vec at here is more efficient, for avoiding call into(). |
The situation is simply that we have a
The important part is cheap cloning. |
I just looked at how bytes works, as I assumed it would require an additional allocation (as Arc<Vec> would). It delays constructing the |
For avoid cargo clippy raise `mutable_key_type error when use PeerId as HashSet/HashMap 's key.
I try to using Arc<Vec> to replace Bytes. |
@@ -123,7 +123,7 @@ impl PeerId { | |||
/// equality of peer IDs. That is, two peer IDs may be considered equal | |||
/// while having a different byte representation as per `into_bytes`. | |||
pub fn into_bytes(self) -> Vec<u8> { | |||
self.multihash.to_vec() | |||
self.multihash.as_ref().clone() | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this should be replaced with an AsRef<[u8]>
or fn as_bytes(&self) -> &[u8]
and defer cloning to the call site if necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and an even better solution would be to use Multihash
internally, since it is stack allocated and use an Arc<PeerId>
if efficient cloning is required. For cid we just implement Copy
. This also has the advantage that Vec<PeerId>
only requires a single allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the reason for this is that the kademlia buckets require something that implements Borrow<[u8]>
so I guess this is the best that can be done for now
What is the problem with continuing to use |
It's an annoyance for all projects that use clippy and the only advantage you get is you defer allocating the arc to the first clone. Something like peeid should be stack allocated and implement the copy trait so that it can be used in collections or boxes or arcs, and a lot of work was done on multihash to make it stack allocated so that it composes well with other rust types. Many projects don't use Tokio or hyper, but as I said, no one would have cared it if clippy weren't forcing buggy checks on people. I already disabled it in the codebase I'm working on. |
I agree that if it makes semantic sense, types should be stack allocated. It's just that replacing |
I don't see it being a worse solution. As I explained I think it should be stack allocated, but since Bytes is already creating an Arc<Vec> internally it barely makes a difference. Do you have a reason to believe it will lead to a measurable performance degradation in your codebase? |
Opened a PR for stack allocating PeerId which also makes clippy happy in #1874 |
|
But in PeerId, we do not support convert `static slice to PeerId, and also does not support update, so the two points are not a good reason to keep Bytes. I think #1874 is a good solution. |
#1874 is approved, so I close this pr. |
For avoiding cargo clippy raise
mutable_key_type
error when using PeerId as HashSet/HashMap's key.