Skip to content

Minor sharing-map improvements, used to avoid copying in value_sett #4539

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

Merged

Conversation

smowton
Copy link
Contributor

@smowton smowton commented Apr 15, 2019

This adds sharing_mapt::erase_if_exists, ::iterate and ::update, and uses them to avoid copying entries in value_sett. The value_sett changes are much easier to review if you diff without whitespace sensitivity.

Note erase_if_exists isn't used in this PR (it's used out-of-tree), but is also the most simple of the additions.

Copy link
Collaborator

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me, except:

  1. It would be good for @danpoe to take a look if he's available.
  2. The last commit includes a lot of whitespace changes.
  3. Any data on how much of a performance difference this makes?

@smowton
Copy link
Contributor Author

smowton commented Apr 15, 2019

I verbally ran these by @danpoe as I went but yes please do take a look. The whitespace is unavoidable per clang-format I'm afraid, due to a 2-char indent difference between iterate-with-lambda and a for-loop.

Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: 8118903).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/108399530

Copy link
Contributor

@danpoe danpoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. I'd also be curious if there's a performance difference.

leaft *lp = cp->find_leaf(k);
PRECONDITION(lp != nullptr); // key must exist in map

lp->mutate_value(mutator);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a debugging check here that tests if the mutated element is different from the old element? (if fail_if_equal is set, similar to the invariant in replace())

@danpoe
Copy link
Contributor

danpoe commented Apr 16, 2019

We should also update the documentation at the top of sharing_map.h to mention update().

@smowton
Copy link
Contributor Author

smowton commented Apr 16, 2019

@tautschnig @danpoe conducted a quick micro-benchmark:

Procedure: populate a value-set with 100K keys, each with 10 values. Modify half the keys by adding 1 extra value, then make-union the two value sets.

Union operation took ~300ms with these changes, or ~750ms without them. The direction of the union made little difference (in one direction it would be a no-op; in one direction it would add a single value to 50k entries), suggesting the cost of editing 50k keys in place is small compared to the cost of copying 100k values out in order to edit them.

@smowton smowton force-pushed the smowton/feature/sharing-map-improvements branch from 8118903 to 927778e Compare April 16, 2019 14:17
@smowton
Copy link
Contributor Author

smowton commented Apr 16, 2019

@tautschnig @danpoe you might want to re-review; I made @danpoe's requested changes re: checking the update makes a change; this required me to add a flag so invariants can throw exceptions instead of aborting (so I could unit test them) and I also fixed replace's debug mode at the same time.

smowton added 5 commits April 16, 2019 21:58
Just saves repeating the if-has-key-then-erase pattern
This is generally a dangerous thing to do, but is useful for unit testing
This permits an in-place update, avoiding needless copy-out / mutate / move-in cycles for
expensive-to-copy value types without leaking a non-const reference to a value.
This gives a simple const iterator without copying the whole dataset.
The make_union and update_entry maps are switched from a copy -> mutate -> move-if-changed
workflow to compare-in-place -> update-in-place-if-needed one. This will be faster so long
as map iteration and inspection is faster than copying.

The output routine simply avoids a needless temporary vector.
@smowton smowton force-pushed the smowton/feature/sharing-map-improvements branch from 927778e to ff16508 Compare April 16, 2019 21:20
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: ff16508).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/108601221

@tautschnig tautschnig merged commit 9f3b058 into diffblue:develop Apr 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants