-
Notifications
You must be signed in to change notification settings - Fork 913
Improve performance of generated enum methods #2693
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
Conversation
## Motivation Generated enums use a standard `fromValue` method to resolve a string value (usually received on the wire) to the corresponding enum. The existing implementation is not optimal for a few reasons: 1. It calls `Enum#values()`, which must allocate a new array every time 2. It iterates the entire array with O(N) complexity The generated `knownValues` follows a similar pattern, plus it does not take advantage of `EnumSet`, which is typically faster than HashSet. These are minor optimization concerns, however many code paths repeatedly call `fromValue()` (as opposed to caching it). ## Modifications * For each generated enum, store a value map which maps the string value to the corresponding enum constant value. Use this map for `fromValue`. * Use an EnumSet for `knownValues`. * Create new `CollectionUtils.index()` & `EnumUtils.index()` methods to facilitate the common use case of constructing a unique index lookup map ## Result * `fromValue` changes from O(N) to O(1) * Minor increase in memory overhead from storing a static map, but reduced allocation from creating new arrays every method call
for (V value : values) { | ||
K index = indexFunction.apply(value); | ||
V prev = map.put(index, value); | ||
Validate.isNull(prev, "No duplicate indices allowed but both %s and %s have the same index: %s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Query : Since we are indexing to unique Converted type should that be reflected in the function name ?
In some case in future I might even want to index duplicate value in where I would expect Map<K, List> might have difficulty to use the same function name in this class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point/question.
My thinking is that indexing like this would be the common/standard use case, where users expect unique indices, and if we wanted to extend this to something like multi-map support, then that new function name would be specialized to differentiate. E.g., index
vs indexMulti
, or similar.
However, since the current function can throw, then perhaps there is an argument for giving this one more explicit naming. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed index
to uniqueIndex
.
## Motivation Generated enums use a standard `fromValue` method to resolve a string value (usually received on the wire) to the corresponding enum. The existing implementation is not optimal for a few reasons: 1. It calls `Enum#values()`, which must allocate a new array every time 2. It iterates the entire array with O(N) complexity The generated `knownValues` follows a similar pattern, plus it does not take advantage of `EnumSet`, which is typically faster than HashSet. These are minor optimization concerns, however many code paths repeatedly call `fromValue()` (as opposed to caching it). ## Modifications * For each generated enum, store a value map which maps the string value to the corresponding enum constant value. Use this map for `fromValue`. * Use an EnumSet for `knownValues`. * Create new `CollectionUtils.index()` & `EnumUtils.index()` methods to facilitate the common use case of constructing a unique index lookup map ## Result * `fromValue` changes from O(N) to O(1) * Minor increase in memory overhead from storing a static map, but reduced allocation from creating new arrays every method call
Kudos, SonarCloud Quality Gate passed! |
…43782f0c0 Pull request: release <- staging/75cecad7-0108-47c2-889d-fa443782f0c0
Motivation
Generated enums use a standard
fromValue
method to resolve a stringvalue (usually received on the wire) to the corresponding enum. The
existing implementation is not optimal for a few reasons:
Enum#values()
, which must allocate a new array every timeThe generated
knownValues
follows a similar pattern, plus it does nottake advantage of
EnumSet
, which is typically faster than HashSet.These are minor optimization concerns, however many code paths
repeatedly call
fromValue()
(as opposed to caching it).Modifications
to the corresponding enum constant value. Use this map for
fromValue
.knownValues
.CollectionUtils.index()
&EnumUtils.index()
methods tofacilitate the common use case of constructing a unique index lookup map
Result
fromValue
changes from O(N) to O(1)reduced allocation from creating new arrays every method call
Types of changes
Checklist
mvn install
succeedsLicense