Speed up push by expanding triple_mut - #557
Conversation
|
32 bytes can be safely ignored as not meaningful |
|
can you paste the improvements table?? |
|
|
improvements are really striking for what the change does |
|
was this related to #361?? |
I still can't reproduce that, but this should improve that anyway. |
|
I'm not sure I can justify a full patch release from this even though improvements are meaningful we should try to avoid releasing two versions within three days at least, as a rule of thumb this undoubtedly should be published soon |
|
I've just noticed that Lines 1461 to 1467 in fadb3b8 That might also be improvable. I'll look into it. |
|
is it a case against using if |
|
The problem with this optimization is the potential bloat (and it makes the code more verbose/less maintainable), so it's probably only worth adding it to hot code. |
|
code can always be refactored, I don't think that's an issue I haven't started going intra-module to see how to refactor things much, but there is a lot of unnecessary stuff everywhere if you look at it, it's the same pattern always you can potentially extract that to a function that's always inlined which takes a it just looks so surreal that moving that affects codegen so much |
|
I've implemented this for Should I submit it anyway, even if the change is unnoticable in most cases, and it makes the code harder to read? Unrelated: Since fn reserve_one_unchecked(&mut self) -> (NonNull<A::Item>, &mut usize) {
debug_assert_eq!(self.len(), self.capacity());
let new_cap = self
.len()
.checked_add(1)
.and_then(usize::checked_next_power_of_two)
.expect("capacity overflow");
infallible(self.try_grow(new_cap));
unsafe { self.data.heap_mut() }
}Then the if blocks that are repeated could just be: if *len_ptr == self.capacity {
(ptr, len_ptr) = self.reserve_one_unchecked();
}I've checked, and this lowers binary size in both debug and release builds. |
|
I don't think it's a good idea to complicate if the private function |
It's worth noting that it's marked |
|
okay, can we do what it does in a simpler way?? it makes sense that removing that function would also put in doubt we currently have like four different since this is v1, I think it's better to shrug our shoulders if there are performance gains by making it return |
|
I've benchmarked a few different combinations of changes, these are the ones that weren't eliminated:
Note that the changes in speed only apply to a vec that needs to be expanded (I benchmarked adding 16 elements to a The second option changes the blocks to self.reserve_one_unchecked();
(ptr, len_ptr) = self.data.heap_mut(); since that improves debug builds for some reason, and also looks nicer than the original. Are either of these worth doing? |
|
I'm not sure to be honest is the juice worth the squeeze?? I wouldn't take anything <1% change in speed as proof of anything I think we probably have other optimizations that we haven't touched that working on them has a higher ROI use your judgement on whether they are worth it, and I'd simply say have the one of the three alternatives that makes the codebase consistent and easier to understand if you think one is worth it, open a PR |
See #379.
This seems to increase binary size by 32 bytes (on a release build, it's closer to 896 in debug), although it might end up being more depending on how many times
pushis inlined.