-
- Notifications
You must be signed in to change notification settings - Fork 1.7k
Improve performance and avoid memory consumption if logging primitive arrays as parameters #3645
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
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.
Looks good to me.
Can you also add a benchmark to ParameterFormatterBenchmark for the old and new version? Due to scalar inlining, str.append(Arrays.toString((int[]) o)) might actually also become GC-free on some JVMs.
log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java Outdated Show resolved Hide resolved
log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java Outdated Show resolved Hide resolved
log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java Show resolved Hide resolved
| All commits in this PR must have verified signatures, so you need to:
|
4b68e44 to 3494eb4 Compare | I doubt that any JVM could optimize away the Arrays.toString() call, I have only seen more or less constants strings go. |
| I tried to sign the commits by executing your command - is it ok now? About resolving conversion: am I doing that if I have replied or you if you think my reply was ok? |
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.
Looks almost good to go, thanks!
One last thing: can you add a changelog entry in src/changelog/.2.x.x/. Look at the other entries for inspiration.
The change type for performance improvements are either fixed or changed.
log4j-perf-test/src/main/java/org/apache/logging/log4j/message/ParameterFormatterBenchmark.java Outdated Show resolved Hide resolved
| Thanks, I'll merge it as soon as the required tests pass. |
It is one of the design goals of Log4j "to deliver excelling performance without almost any burden on the Java garbage collector."
However this is currently not true for primitive arrays, here Log4j allocates unneeded temporary strings if a primitive array is logged as parameter.
Current implementation:
Method ParameterFormatter.appendArray() delegats to java.util.Arrays.toString() which then allocates a new StringBuilder to return a String which is then added to the existing StringBuilder.
Improved implementation:
For all primitive types, a method like ParameterFormatter.appendArray(int[], StringBuilder) has been added which is called by ParameterFormatter.appendArray() and avoids the unnecessary object creation.
A JHM benchmark shows that this changes increases performance and reduces memory consumption to zero:
Tests have been added to ParameterFormatterTest