Ensure equality when hashing default args and no args in actions#10341
Conversation
|
This can't be serviced to Stable as that code doesn't exist in Stable. Be careful with those servicing tags... |
lhecker
left a comment
There was a problem hiding this comment.
Woops I meant to comment and not approve.
I'll request changes, since I can't undo an approval.
|
It seems |
My bad. Wasn't sure if |
Yeah. This is where I wish I took a course on cryptography and hashing in college haha. I don't think that theoretically there could be no collisions. That said, in practice, we haven't seen any so we're probably fine for now. |
lhecker
left a comment
There was a problem hiding this comment.
Long term a more robust equality-solution would be nice, but that's for another day.
Until then: LGTM.
| #define ON_ALL_ACTIONS_WITH_ARGS(action) \ | ||
| case ShortcutAction::action: \ | ||
| /* If it does, hash the default values for the args.*/ \ | ||
| hashedArgs = gsl::narrow_cast<size_t>(make<action##Args>().Hash()); \ |
There was a problem hiding this comment.
I low-key hate that this requires constructing an entire object filled with default values to calculate a hash; it could be wildly expensive. Can you profile to make sure we're not making a bunch of objects just to destroy them moments later? Both CPU and memory-wise.
There was a problem hiding this comment.
I feel like we could get around this by maintaining a static .Empty singleton of each of these if this is what we need to Hash... or cache the hash of the empty one as a singleton...
There was a problem hiding this comment.
To be fair though none of the ActionArgs constructors are complex at the moment.
As such I "propose" the following solution:
- add
constexprto the default constructors of all ActionArgs classes - add
constexprto all theirHash()member functions - add
constexprto the getters of theACTION_ARGandWINRT_PROPERTYmacros - write:
case ShortcutAction::action: hashedArgs = implementation::action##Args{}.Hash(); break;
This will probably compile to constants in release mode and in debug mode it won't allocate anything on the heap.
There was a problem hiding this comment.
That will be illegal because we're not using winrt::make for something that's known to be a runtimeclass.
03dd81d to
a5e6d46
Compare
a5e6d46 to
d83a764
Compare
|
Added Took the average of 5 perf traces in VS:
With this change, we see an average increase of 756.8 Allocations and 70.82 Heap Size. Scenario:
These hashes are always first used in |
Co-authored-by: Dustin L. Howett <[email protected]>
|
Hello @DHowett! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
) ## Summary of the Pull Request #10297 found a bug in `ActionMap` where the `ToggleCommandPalette` key chord could not be found using `GetKeyBindingForAction`. This was caused by the following: - `AddAction`: when adding the action, the `ActionAndArgs` is basically added as `{ToggleCommandPalette, ToggleCommandLineArgs{}}` (Note the default ctor used for the action args) - `GetKeyBindingForAction`: we're searching for an `ActionAndArgs` structured as `{ToggleCommandPalette, nullptr}` - Since these are _technically_ two different actions, we are unable to find it. This issue was fixed by making the `Hash(ActionAndArgs)` function smarter! If the `ActionAndArgs` has no args, but the `ShortcutAction` _supports_ args, generate the args using the default ctor. By making `Hash()` smarter, everybody benefits from this logic! We can basically now enforce that `ActionAndArgs{ <X>, nullptr } == ActionAndArgs{ <X>, <default_ctor> }`. ## Validation Steps Performed - Added a test. - Tested this on #10297's branch and this does fix the bug (cherry picked from commit b3b6484)
Summary of the Pull Request
#10297 found a bug in
ActionMapwhere theToggleCommandPalettekey chord could not be found usingGetKeyBindingForAction.This was caused by the following:
AddAction: when adding the action, theActionAndArgsis basically added as{ToggleCommandPalette, ToggleCommandLineArgs{}}(Note the default ctor used for the action args)GetKeyBindingForAction: we're searching for anActionAndArgsstructured as{ToggleCommandPalette, nullptr}This issue was fixed by making the
Hash(ActionAndArgs)function smarter! If theActionAndArgshas no args, but theShortcutActionsupports args, generate the args using the default ctor.By making
Hash()smarter, everybody benefits from this logic! We can basically now enforce thatActionAndArgs{ <X>, nullptr } == ActionAndArgs{ <X>, <default_ctor> }.Validation Steps Performed