On Wed, 27 Jul 2022 22:56:39 GMT, David Schlosnagle <d...@openjdk.org> wrote:
> I would like to contribute an optimized version of > `StackTraceElement#toString()` that uses a single StringBuilder throughout > creation to avoid intermediate `String` allocations. > `StackTraceElement#toString()` is used in a number of JDK code paths > including `Throwable#printStackTrace()`, as well as many JDK consumers may > transform `StackTraceElement` `toString()` in logging frameworks capturing > throwables and exceptions, and diagnostics performing dumps. > > Given this usage and some observed JFR profiles from production services, I'd > like to reduce the intermediate allocations to reduce CPU pressure in these > circumstances. I have added a couple benchmarks for a sample > `Throwable#printStackTrace()` converted to String via `StringWriter` and > individual `StackTraceElement` `toString`. The former shows ~15% improvement, > while the latter shows ~40% improvement. > > Before > > Benchmark Mode Cnt Score Error > Units > StackTraceElementBench.printStackTrace avgt 15 167147.066 ± 4260.521 > ns/op > StackTraceElementBench.toString avgt 15 132.781 ± 2.095 > ns/op > > > After > > Benchmark Mode Cnt Score Error > Units > StackTraceElementBench.printStackTrace avgt 15 142909.133 ± 2290.720 > ns/op > StackTraceElementBench.toString avgt 15 78.939 ± 0.469 > ns/op src/java.base/share/classes/java/lang/StackTraceElement.java line 366: > 364: if (!dropClassLoaderName() && classLoaderName != null && > !classLoaderName.isEmpty()) { > 365: prefixClassLoader = true; > 366: length += classLoaderName.length() + 1 /* '/' */; Do we still need this comment `/* '/' */`? src/java.base/share/classes/java/lang/StackTraceElement.java line 400: > 398: dest.append(fileName) > 399: .append(':') > 400: .append(Integer.toString(lineNumber)) I think `Integer.toString(lineNumber)` is redundant here, you can pass `int` directly ------------- PR: https://git.openjdk.org/jdk/pull/9665