Hi Remi,

Yes, setting up a StackWalker is more or less free. It is just
wrapping a set of options.

public class StackWalkerPerf {

    static final StackWalker sw =
StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);

    @Benchmark
    public StackWalker stackWalkerSetup() {
        return StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
    }

    @Benchmark
    public Class<?> stackWalkerCallerClass() {
        return sw.getCallerClass();
    }

    @Benchmark
    public Lookup reflectionCallerClass() {
        return MethodHandles.lookup();
    }
}

Benchmark                               Mode  Cnt     Score    Error  Units
StackWalkerPerf.stackWalkerSetup        avgt   10    11.958 ±  0.353  ns/op
StackWalkerPerf.reflectionCallerClass   avgt   10     8.511 ±  0.415  ns/op
StackWalkerPerf.stackWalkerCallerClass  avgt   10  1269.825 ± 66.471  ns/op

I'm using MethodHandles.lookup() in this test because it is cheapest
way to invoke Reflection.getCallerClass() without any tricks.
So real performance is likely better.

/Kasper

On Tue, 2 Jul 2019 at 13:53, Remi Forax <fo...@univ-mlv.fr> wrote:
>
> Hi Kasper,
> did you store the StackWalker instance in a static final field ?
>
> Rémi
>
> ----- Mail original -----
> > De: "Kasper Nielsen" <kaspe...@gmail.com>
> > À: "core-libs-dev" <core-libs-dev@openjdk.java.net>
> > Envoyé: Mardi 2 Juillet 2019 11:09:11
> > Objet: Slow performance of StackWalker.getCallerClass() vs 
> > Reflection.getCallerClass()
>
> > Hi,
> >
> > Are there any security reasons for why StackWalker.getCallerClass()
> > cannot be made as performant as Reflection.getCallerClass()?
> > StackWalker.getCallerClass() is at least 100 times slower then
> > Reflection.getCallerClass() (~1000 ns/op vs ~10 ns/op).
> >
> > I'm trying to retrofit some existing APIs where I cannot take a Lookup
> > object to do some access control checks.
> > But the performance of StackWalker.getCallerClass() is making it impossible.
> >
> > Best
> >  Kasper

Reply via email to