-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Fix sizing of Maps #3868
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
base: 2.x
Are you sure you want to change the base?
Fix sizing of Maps #3868
Conversation
Fix several instances where Maps were sized incorrectly when the number of elements to insert is known; specifying the capacity without taking into account the load factor meant it would always result in a rehash / resize operation. To this end, add a simple Maps utility class that handles the capacity calculation, much like the static HashMap.newHashMap helper that was added in JDK19.
Thanks so much for the patch. Would you mind sharing some context, please?
Did you observe a particular performance issue?
… Message ID: ***@***.***>
|
I don't recall how I stumbled upon it or if it showed up in any performance profiles (it definitely has for other libraries). It's just a common thing I've noticed across various projects (e.g., spring and grpc-java) since the HashMap constructor is a foot gun and it's not easy to do correctly until Java 19. Since the intent here was to presize the map, and we know how many elements to insert, it just seemed to make sense to size it so we always avoid the resize / rehash operations. |
Hi @kilink, Adding a new utility class to Could you instead:
I agree with @vy that, without clear benchmark results, the value of this enhancement is questionable. We avoid using |
I'm against enhancements without convincing figures obtained from benchmarks mapping to real-world use cases. If this optimization yields a tangible benefit on the hot path, provide a reproducer please. |
I personally don't think it's worthwhile to spend time writing a benchmark for what amounts to a bug fix / correctness issue. If you'd rather not accept the change, feel free to close the issue. I'll leave my rationale for fixing it however:
I assume the main point of contention is the addition of a utility class, and I agree it is ugly, but it's a stopgap until (?) Log4j can use the static |
@@ -206,7 +207,7 @@ public void close() { | |||
} | |||
|
|||
private void closeMap() { | |||
final Map<String, String> valuesToReplace = new HashMap<>(originalValues.size()); | |||
final Map<String, String> valuesToReplace = Maps.newHashMap(originalValues.size()); |
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.
I've reviewed all log4j-api
and log4j-core
changes, and found this to be only change that one might claim to be of importance. I prefer a PR that
- Replaces all
HashMap#new(int)
calls with aHashMap#new()
(Since they're all incorrectly implemented, it is better to just stick to defaults.) - Replaces only this line in
CloseableThreadContext
withnew HashMap((int) Math.ceil(originalValues.size() / 0.75))
@ppkarwasz, WDYT?
Fix several instances where Maps were sized incorrectly when the number of elements to insert is known; specifying the capacity without taking into account the load factor meant it would always result in a rehash / resize operation.
To this end, add a simple Maps utility class that handles the capacity calculation, much like the static HashMap.newHashMap helper that was added in JDK19.
Checklist
Before we can review and merge your changes, please go through the checklist below. If you're still working on some items, feel free to submit your pull request as a draft—our CI will help guide you through the remaining steps.
✅ Required checks
License: I confirm that my changes are submitted under the Apache License, Version 2.0.
Commit signatures: All commits are signed and verifiable. (See GitHub Docs on Commit Signature Verification).
Code formatting: The code is formatted according to the project’s style guide.
Build & Test: I verified that the project builds and all unit tests pass.
How to build the project
Run:
./mvnw verify
See the build instructions for details.
🧪 Tests (select one)
📝 Changelog (select one)
src/changelog/.2.x.x
. (See Changelog Entry File Guide).