Open fabianbs96 opened 1 year ago
Merging #271 (7eec5f9) into master (5875f77) will decrease coverage by
0.07%
. The diff coverage is87.40%
.
:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.
@@ Coverage Diff @@
## master #271 +/- ##
==========================================
- Coverage 90.53% 90.46% -0.07%
==========================================
Files 119 119
Lines 12144 12379 +235
==========================================
+ Hits 10994 11199 +205
- Misses 1150 1180 +30
Files | Coverage Δ | |
---|---|---|
immer/detail/util.hpp | 82.60% <ø> (-0.25%) |
:arrow_down: |
immer/map.hpp | 99.09% <100.00%> (+0.07%) |
:arrow_up: |
test/algorithm.cpp | 89.69% <100.00%> (+0.67%) |
:arrow_up: |
test/map/generic.ipp | 99.23% <98.75%> (+0.10%) |
:arrow_up: |
immer/detail/hamts/champ.hpp | 86.16% <80.60%> (-1.00%) |
:arrow_down: |
Hi @arximboldi, sorry for the late reply. Thanks for the suggestion, this sounds good. I will incorporate your requested changes. However, due to my own time constraints I cannot predict as of now, when this will be completed.
No worries. Thank you a lot in any case for the time that you've already put into this!
Story
As a user of
immer
, I want to efficiently build up nestedmap<set>
structures in an incremental way until reaching a fixpoint, achieving maximum performance. This involves frequent updates of the nestedset
s inside the map. The obvious solution for this problem is using theimmer::map::update
function to update the inner sets. However, I have found thatupdate
always re-allocates -- even if the updated value is identical to the already present value leaving a lot of performance on the table. This for example happens if inserting an element to an inner set that has already been present.As a fallback solution, I currently do the following:
Whereas I really want to do:
Solution Proposal
As a solution to above problem, I propose a new API
try_update
withinimmer::map
that works similar toupdate
, just adds an additional equality check on the result of the callbackfn
and in case of equality leaves the map unchanged.This PR implements
try_update
on thechamp
and provides an according public API toimmer::map
. In addition, it fixes a minor issue that thechamp::update
function takes the key by const-ref, although the underlyingdo_update
function can deal with perfectly forwarded keys.Design decisions:
do_try_update
anddo_try_update_mut
within an inner struct allowing to recursively call mentioned functions without specifying the template arguments again.do_update[_mut]
and use anullptr
node as indicator that nothing has changed.std::equal_to
for value-equals can even be elided completely. As a policy, when to pass by value, I implemented thebyval_if_possible
type-trait preferring by-value for trivial types that are not larger than two pointers. This more-or-less matches the behavior of the x86-64 parameter passing conventions of the Itanium ABI (refer to https://gitlab.com/x86-psABIs/x86-64-ABI/ chapter 3.2.3 Parameter Passing)