-
Notifications
You must be signed in to change notification settings - Fork 1.2k
object_id: back id types by Box<[u8]> instead of Vec<u8>
#9930
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,9 +27,9 @@ pub trait ObjectId { | |
| } | ||
|
|
||
| // Defines a new struct type with visibility `vis` and name `ident` containing | ||
| // a single Vec<u8> used to store an identifier (typically the output of a hash | ||
| // function) as bytes. Types defined using this macro automatically implement | ||
| // the `ObjectId` and `ContentHash` traits. | ||
| // a single Box<[u8]> used to store an identifier (typically the output of a | ||
| // hash function) as bytes. Types defined using this macro automatically | ||
| // implement the `ObjectId` and `ContentHash` traits. | ||
| // Documentation comments written inside the macro definition will be captured | ||
| // and associated with the type defined by the macro. | ||
| // | ||
|
|
@@ -46,7 +46,7 @@ macro_rules! id_type { | |
| ) => { | ||
| $(#[$attr])* | ||
| #[derive($crate::content_hash::ContentHash, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] | ||
| $vis struct $name(Vec<u8>); | ||
| $vis struct $name(Box<[u8]>); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might also be worth considering
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I think my answer is the same as above: it's hard to know without someone doing some profiling.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I can tell, the allocation cost isn't significant. What matters more is the cache locality of things like
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am by no means a Rust expert, but I just happened to come across a YouTube video called "Use Arc instead of Vec" by Logan Smith (no link to avoid coming across as spam :p), and in it he provides arguments for always preferring |
||
| $crate::object_id::impl_id_type!($name, $hex_method); | ||
| }; | ||
| } | ||
|
|
@@ -56,13 +56,13 @@ macro_rules! impl_id_type { | |
| #[allow(dead_code)] | ||
| impl $name { | ||
| /// Creates a new instance of this id type from the given bytes. | ||
| pub fn new(value: Vec<u8>) -> Self { | ||
| Self(value) | ||
| pub fn from_vec(value: Vec<u8>) -> Self { | ||
| Self(value.into()) | ||
| } | ||
|
|
||
| /// Creates a new instance of this id type from the given byte slice. | ||
| pub fn from_bytes(bytes: &[u8]) -> Self { | ||
| Self(bytes.to_vec()) | ||
| Self(bytes.into()) | ||
| } | ||
|
|
||
| /// Parses the given hex string into an ObjectId. | ||
|
|
@@ -75,7 +75,7 @@ macro_rules! impl_id_type { | |
|
|
||
| /// Parses the given hex string into an ObjectId. | ||
| pub fn try_from_hex(hex: impl AsRef<[u8]>) -> Option<Self> { | ||
| $crate::hex_util::decode_hex(hex).map(Self) | ||
| $crate::hex_util::decode_hex(hex).map(Self::from_vec) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -119,7 +119,7 @@ macro_rules! impl_id_type { | |
| } | ||
|
|
||
| fn to_bytes(&self) -> Vec<u8> { | ||
| self.0.clone() | ||
| self.0.to_vec() | ||
| } | ||
|
|
||
| fn hex(&self) -> String { | ||
|
|
||
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.
optional: It still may be useful to provide some
to_vec(),from_vec()functions so callers can migrate.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.
The
new()function still takes aVec<u8>andto_bytes()still returnsVec<u8>, so that should be fine. It's actually theBox<[u8]>versions that are missing. We may want to add those and see if we can avoid conversions to/fromVec<u8>in some places.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.
Yes, we should probably rename
new(Vec<u8>)tofrom_vec(Vec<u8>).I have no idea if saving 8 bytes matters, but I'm not against it. If we decide to inline up to 32 or 64 bytes, there's room for a capacity field.
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 don't know if it matters either, and I don't feel strongly either way.
Do you mean using something like
SmallVec<[u8; 32]>? I suppose that's another option. I don't know how to decide if that's better without someone spending time doing some profiling.Done.