Ceki,

Looks like the benchmark code is from https://github.com/qos-ch/slf4j/pull/271

Looks like the benchmark code is doing a collection so perhaps that is some of 
the performance hit?
Have you benchmarked java.util.LogRecord.getSourceClassName() to compare with 
your StackWalker benchmark?

https://github.com/openjdk/jdk/blob/master/src/java.logging/share/classes/java/util/logging/LogRecord.java#L754

Jason

________________________________________
From: core-libs-dev <core-libs-dev-r...@openjdk.java.net> on behalf of Ceki 
Gülcü <c...@qos.ch>
Sent: Wednesday, April 6, 2022 4:26 PM
To: core-libs-dev
Subject: Re: fast way to infer caller


Hi Rémi,

Thank you for your answer.

According to some benchmarks on a i7-8565U Intel CPU (quite average
CPU), here are the costs of computing the caller class via different
methods:

using new Throwable().getStackTrace: 11 microseconds per call
using StackWalker API: 1.8 microseconds per call
using SecurityManager: 0.9 microseconds per call

While a six fold improvement (StackWalker compared to new Thorowable) is
nothing to sneeze at, the performance of StackWalker is not as good as
with a custom SecurityManager.

I have not said so explicitly but the aim here is to allow the user to
obtain a new logger by calling LoggerFactory.getLogger() with no
arguments with the returned logger named after the caller class.

Spending 1 or 2 microseconds for this call is OK if the logger is a
static field. However, if the logger is an instance field, then spending
2 microseconds per host object instance just to obtain a logger might
have a noticeable impact on performance. It follows that the performance
of LoggerFactory.getLogger() must be exceptionally good, assuming we
wish to avoid having the user accidentally shooting herself on the foot,
ergo the 100 nanosecond performance per call requirement.

Noting that invoking MethodHandles.lookup().lookupClass() seems very
fast (about 2 nanoseconds), I would be very interested if  new
lookup(int index) method were added to java.lang.invoke.MethodHandles
class, with index designating the desired index on the call stack.

Does the above make sense? How difficult would it be to add such a method?

--
Ceki Gülcü


On 4/6/2022 5:52 PM, Remi Forax wrote:
> ----- Original Message -----
>> From: "Ceki Gülcü" <c...@qos.ch>
>> To: "core-libs-dev" <core-libs-dev@openjdk.java.net>
>> Sent: Wednesday, April 6, 2022 5:30:51 PM
>> Subject: fast way to infer caller
>
>> Hello,
>
> Hello,
>
>>
>> As you are probably aware, one of the important primitives used in
>> logging libraries is inferring the caller of a given logging statement.
>> The current common practice is to create a throwable and process its
>> stack trace. This is rather wasteful and rather slow. As an alternative,
>> I have tried using the StackWalker API to infer the caller but was
>> unsatisfied with the performance.
>>
>> MethodHandles.lookup().lookupClass() looks very promising except that
>> there is no way to specify the depth.
>>
>> I am looking for a method to obtain the Nth caller at a cost of around
>> 100 to 200 nanoseconds of CPU time.  Do you think the JDK could cater
>> for this use case?
>
> We have designed the StackWalker with that in mind
> https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/StackWalker.html
>
> see the discussion on StackWalker.getCallerClass()
> https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/StackWalker.html#getCallerClass()
>

Reply via email to