On Wed, 27 Jul 2022 22:56:39 GMT, David Schlosnagle <[email protected]> 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