-
Notifications
You must be signed in to change notification settings - Fork 5
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
Performance Improvements #1
Comments
@mccolljr I wonder if it's possible to store also might make sense to write a wrapper struct that enforces the invariant of contiguous elements (i.e. never having an array that is struct Segment<T>([Option<T>; 4]);
struct SegVec<T> {
cap: usize,
size: usize,
segments: Vec<Segment<T>>,
} |
@connorskees That's a good idea to reduce the overhead of each segment, but I think it wouldn't work here since one of the properties I want to maintain is that each doubling of vector size only requires a single allocation, which means that each new segment is necessarily progressively larger than the last. However, I've been playing with this over the last day and I've realized that:
Doing this could allow an arbitrarily large number of items to be stored in the |
Status on this: I modified the |
Notice from the performance department: I expressed before that I am not very fond of using 'thin-vec', now while playing around with the benchmark and different features (trying to see if cacheline alignment would speed things up) I noticed that thin-vec makes things much slower (30-60% decrease in performance). I'd expected it to be at least as fast as without :/ |
This is good to know. This was an early attempt to keep the segment header size as small as possible, but the extra indirection needed to access segment length and capacity probably causes cache misses for a very marginal gain in space segment header size. When I have some time this week I intend to abstract the storage into a trait so that a consumer of the data structure can choose their own storage implementation, and I will provide a default implementation for |
i am playing with what i noted before:
This way the Segments becomes thin pointers (later ideally in a SmallVec) |
When you make this a Trait, please pass |
'Segments<T, C: MemConfig>' should become a newtype w/ trait too. Rationale: MemConfig determines the segment_size() arithmetically, but Vec / slice based storage backends could query that without calculation, only my planned thin '*mut T' would need arithmetic here. |
another note mostly for myself, but opinions would be welcome: while the 'SegmentCache' try was working it turned out to be way to intrusive to be useful and 'Linear' outperformed it in many cases. I am thinking about reviving the caching idea only for Slices:
So far thats only in brainfart stage. So Caching will be opt-in with some (3 usize) overhead. Default will stay as is. Implemented only for Slice, not SliceMut since caching only works well for accesses within the same segment. One shouldo clone Slices when working on different parts of the Slice, SliceMut cant be cloned (eventually some SliceMut::split_at_mut() may become handy, then caching may be ok) I have no immediate need for this, I just write it down here, would be a low hanging fruit to be implemented later and improve indexing operations for Slices into Proportional and Exponential configured SegVecs. |
Right now, the implementation is significantly slower than
Vec
for most things. This can be fixed.TODO:
insert
,remove
, anddrain
can copy mem to avoid some iterative shifting.SegVec::with_capacity
inFromIterator
implementationThe text was updated successfully, but these errors were encountered: