RFR: 8291641: Optimize StackTraceElement.toString()

David Schlosnagle duke at openjdk.org
Mon Aug 1 17:31:49 UTC 2022


On Thu, 28 Jul 2022 00:48:32 GMT, Carter Kozak <duke at 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 374:
> 
>> 372:      * @throws IOException If an I/O error occurs
>> 373:      */
>> 374:     private void appendTo(Appendable dest) throws IOException {
> 
> Perhaps this could be package-private for reuse by `Throwable.printStackTrace`, avoiding the intermediate toString.

Yes, I think the `PrintStreamOrWriter` could implement `Appendable` as both `PrintStream` and `PrintWriter` implement `Appendable`. 

https://github.com/openjdk/jdk/blob/348a0521e1cd602c4093955310f838cf4ce4daae/src/java.base/share/classes/java/lang/Throwable.java#L756

This would also potentially allow optimizing away the additional intermediate strings from prefixing the lines with `"\tat "` concatenated with the `StackTraceElement.toString()`

https://github.com/openjdk/jdk/blob/348a0521e1cd602c4093955310f838cf4ce4daae/src/java.base/share/classes/java/lang/Throwable.java#L686-L687

https://github.com/openjdk/jdk/blob/348a0521e1cd602c4093955310f838cf4ce4daae/src/java.base/share/classes/java/lang/Throwable.java#L724-L725

-------------

PR: https://git.openjdk.org/jdk/pull/9665


More information about the core-libs-dev mailing list