Fix extended stack trace (i.e., %xEx) rendering performance regression#3123
Fix extended stack trace (i.e., %xEx) rendering performance regression#3123vy merged 11 commits intoapache:2.xfrom
%xEx) rendering performance regression#3123Conversation
|
@ppkarwasz @vy
2.25.0 SNAPSHOT: around 2.5GB
Initial fix ea9944f reduce to around 300 MB
Will continue to check for improvement |
|
My benchmark shows that these changes are ~10% slower than 2.24.1, and use 3x the heap. That is far better than previous 2.25.0, which was more than 2x slower and used ~15x the heap. What level of performance regression is acceptable? |
They seem more than acceptable to me. These are figures using synchronous logging, right? They seem more than acceptable to me. For asynchronous loggers, the performance regression is probably higher, since the Regardless of the results of asynchronous loggers, I think that the throwable chapter of
If users complain about the asynchronous performance of |
%xEx) rendering performance regression
|
I am still observing a ~10x performance regression. I use the following crude script: import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter;
import java.net.Socket;
public class Log4j2Issue3123 {
public static void main(String[] args) {
final Exception error = createException();
final LogEvent logEvent = Log4jLogEvent.newBuilder().setThrown(error).build();
final ExtendedThrowablePatternConverter converter = ExtendedThrowablePatternConverter.newInstance(null, null);
long startInstantNanos = System.nanoTime();
final StringBuilder buffer = new StringBuilder();
for (int i = 0; i < 5_000_000; i++) {
buffer.setLength(0);
converter.format(logEvent, buffer);
}
double durationSeconds = (System.nanoTime() - startInstantNanos) / 1e9;
System.out.format("took %.3f s%n", durationSeconds);
// 2.24.1 - 1.753 s
// 2.25.0 - 11.281 s
}
private static Exception createException() {
try {
new Socket("localhost", -1);
throw new IllegalStateException("should not have reached here");
} catch (final Exception error) {
return error;
}
}
} |
@jengebr, mind sharing the details about your benchmark, please? |
|
Sure - my benchmark is attached. Be sure to use I vary the scenario by changing the classpath to include the desired log4j version. |
|
@vy I confirm your results; profiling shows your script is bottlenecked on the |
|
@vy @jengebr
|
|
And I noticed that compare to
2.24.1
2.25.0 commit 3fa242a
|
|
I found that current way to load class wastes 4GB more memory, compare to old approach(simple if-else way) according to the profiler. I guess it's the overhead of Stream API. |
|
Also the current way of using |
Awesome findings @alan0428a! 🤩 |
@alan0428a, what do you mean by this? What would be your suggestion instead? |
|
I can confirm that with the
@ppkarwasz, agreed. I will implement the changes you suggested. |








2.25.0-SNAPSHOT#3106, due to Disruptor + many logger.error("aa", new Exception("aaa")),stuck on Th… #3093.%xExto%ex