Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upUse a union to reduce the size of SmallVec [v2] #94
Conversation
arthurprs
force-pushed the
arthurprs:union
branch
from
14d49b6
to
2f677c7
May 10, 2018
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
added a commit
to Vurich/rust-smallvec
that referenced
this pull request
May 22, 2018
This comment has been minimized.
This comment has been minimized.
|
|
arthurprs
force-pushed the
arthurprs:union
branch
from
2f677c7
to
61d1e53
May 22, 2018
arthurprs
force-pushed the
arthurprs:union
branch
from
61d1e53
to
4f968c9
May 22, 2018
This comment has been minimized.
This comment has been minimized.
|
I rebased on master now, the only change I kept was to add the return type to remove_no_inline (to prevent over optimization, specially for Vec). |
| //! Note that `smallvec` can still be larger than `Vec` if the inline buffer is larger than two | ||
| //! machine words. | ||
| //! | ||
| //! To use this feature add `features = ["uuid"]` in the `smallvec` section of Cargo.toml. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
arthurprs
force-pushed the
arthurprs:union
branch
from
8c76eeb
to
35b43c0
May 24, 2018
This comment has been minimized.
This comment has been minimized.
|
It'd be nice to get this moving. It may be interesting for rustc as well. |
This comment has been minimized.
This comment has been minimized.
|
@mbrubeck Do you have time to review these changes? |
| default = ["std"] | ||
|
|
||
| [lib] | ||
| name = "smallvec" | ||
| path = "lib.rs" | ||
|
|
||
| [dependencies] | ||
| unreachable = "1.0.0" | ||
| debug_unreachable = "0.1" |
This comment has been minimized.
This comment has been minimized.
mbrubeck
Jun 1, 2018
Contributor
We may not want to use debug_unreachable, because it is unmaintained and doesn't work correctly in Rust > 1.0: reem/rust-debug-unreachable#6
We could just use unreachable all the time, or write our own debug_unreachable macro, or write a new debug_unreachable-like crate...
This comment has been minimized.
This comment has been minimized.
arthurprs
Jun 2, 2018
Contributor
Makes sense, I'll remove the dependency and add the equivalent macro.
| @@ -350,14 +419,25 @@ impl<A: Array> SmallVec<A> { | |||
| /// ``` | |||
| #[inline] | |||
| pub fn from_vec(mut vec: Vec<A::Item>) -> SmallVec<A> { | |||
| let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len()); | |||
| mem::forget(vec); | |||
| if vec.capacity() <= A::size() { | |||
This comment has been minimized.
This comment has been minimized.
mbrubeck
Jun 1, 2018
Contributor
The documentation says that from_vec does not copy the elements. I think we should keep the current behavior of keeping the items on the heap. Users who want to move them inline if possible can use shrink_to_fit or other methods.
This comment has been minimized.
This comment has been minimized.
Amanieu
Jun 1, 2018
Contributor
This is unfortunately not possible with the new design: there is no way of representing a heap-allocated buffer with a capacity less than A::size(). If self.capacity <= A::size() then the code assumes that the data is in the inline buffer.
This comment has been minimized.
This comment has been minimized.
| @@ -301,7 +370,7 @@ impl<A: Array> Drop for SmallVecData<A> { | |||
| /// assert!(v.spilled()); | |||
| /// ``` | |||
| pub struct SmallVec<A: Array> { | |||
| len: usize, | |||
| capacity: usize, | |||
This comment has been minimized.
This comment has been minimized.
mbrubeck
Jun 1, 2018
Contributor
Using capacity here is a little confusing to me, but I'm not sure what a better name would be. Maybe something like len_cap? Maybe capacity is okay, but there should be a comment here describing the semantics.
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| #[inline] | ||
| fn triple(&self) -> (*const A::Item, usize, usize) { |
This comment has been minimized.
This comment has been minimized.
| while len < *len_ptr { | ||
| let last_index = *len_ptr - 1; | ||
| *len_ptr = last_index; | ||
| ptr::read(ptr.offset(last_index as isize)); |
This comment has been minimized.
This comment has been minimized.
| } else { | ||
| let ptr = self.as_ptr(); | ||
| for i in 0..self.len() { | ||
| ptr::read(ptr.offset(i as isize)); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Great, thanks! I think this is ready but I just want to double-check all the unsafe code before merging it (and give a chance for others to do the same). |
This comment has been minimized.
This comment has been minimized.
|
@bors-servo r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
added a commit
that referenced
this pull request
Jun 6, 2018
This comment has been minimized.
This comment has been minimized.
|
|
arthurprs commentedMay 10, 2018
•
edited by larsbergstrom
Building on top of #92 by @Amanieu
I introduced
triple()andtriple_mut()which removed almost all of the runtime overhead. Performance is very comparable.This change is