> De: "Steven Stewart-Gallus" <stevenselectronicm...@gmail.com>
> À: "mechanical-sympathy" <mechanical-sympathy@googlegroups.com>
> Envoyé: Jeudi 17 Janvier 2019 07:50:13
> Objet: Re: Exotic classes

> I've been working on similar issues trying to optimise something
> heavily.  I made a similar class to this one (I even had a similar
> API) but I found I called it MostlyFinal instead.

> private static final MostlyConstant<Integer> FOO = new MostlyConstant<>(42,
> int.class);
> private static final IntSupplier FOO_GETTER = FOO.intGetter();

> By the way using a different interface than Supplier can give the JVM
> more class hierarchy analysis info and so potentially allow for
> inlining even without static final.

no, CHA only works on class, not on interface. 

> You can also simply use a closure in some cases sort of like this:

> interface IntBox {
>    int get();
> }
> public IntBox makeBox(int x) {
>     return () -> x;
> }

> This is better for inlining because the JVM trusts final fields in VM
> anonymous classes more than yours.  Unfortunately
> TrustStaticFinalFields cannot be a thing by default yet for backwards
> compatibility reasons.

> I think a lot of these things are pretty neat but unfortunately hard
> to package in a generic and usable library because people delving into
> these will want to tear into all the internal details for maximum
> performance.

> I don't really understand your StableField class.  How is it supposed
> to be any faster than MostlyConstant?

It's not the same semantics, you can not change a StableField more than once so 
you have the guarantee that once the field is initialized, no deoptimization 
can occur. 
The other things is the object is not constant, you will get an exception so 
it's hard to misuse that API. 
The last point is that i expect that at some point i will change the 
implementation so the slowpath will cost less than the slowpath of 
MostlyConstant, but i've never had the time to think how to do that in a VM 
independant way (i know how to do that with Hotspot only). 

> I would suggest if you wanted the best speed (in some ways and at a cost of
> memory) you could spin a
> static final class with a method that returns a constantdynamic entry
> and then return a methodhandle to that entry.  This seems possibly
> heavyweight IMO so I'm still thinking about this myself.

better, use a lazy static final field (see [ 
https://bugs.openjdk.java.net/browse/JDK-8209964), | 
https://bugs.openjdk.java.net/browse/JDK-8209964), ] 
i.e. tech javac to either emit a ldc to the ConstantDynamic or do a getfield 
that will trigger the ConstantDynamic initialization if needed. 

> If StringSwitchCallSite being a MutableCallSite seems possibly
> unneeded with a reworked API to me.

but it means that you have if/else branch for String that the program has never 
encounter. 
I prefer to not add all the branches statically but add then at runtime 
dynamically when i know i need then. 

> I am highly suspicious TypeSwitch will increase performance in most cases.
> instanceof checks are highly optimized and give info that allow
> further optimizations.

It depends, if instanceof else ... is slow if you have deep hierarchy, if the 
test are not in the right order of occurence and if you have too many branches. 
But yes, the StringSwitch and the TypeSwitch can be slower/faster than the 
equivalent cascade of if/else. 

> You might want to consider using/abusing the JVM's own inline caching
> behaviour for interfaces for some dispatching.

A MethodHandles.guardWithTest is exactly that ! 

> It's not too hard to create a bag of interface implementations at
> runtime that all dispatch to separate CallSite implementations which
> can be faster than exactInvoker/your own MethodHandle lookup logic
> sometimes.

No, believe me, it's hard. It's the reason i've created (with others) the 
java.lang.invoke API. 

> I considered this for a ThreadLocalCallSite class I was
> making but I'm still not sure about the design.

> So basically one hack to get quicker thread local behaviour is to
> subclass Thread and add your own fields/methods like this:

> ((MyIface)Thread.currentThread()).doSpecific();

> If you add your own bag of interface implementations then you can do
> this dynamically:

> MY_IFACE.invokeExact((BagThread)Thread.currentThread()).bag, ...);

It will not be inlined by the VM :( 

About having a ThreadLocalCallSite, as part of project Loom, we are discussing 
about how associate a value to a part of the callstack. 
Anyway, the VM doesn't have a code cache per thread, there is only a global 
code cache. 

> I'm not sure about the bytecode generation here though. I don't want
> to be too blase about that.

> It looks like you have some benchmarks setup but I don't see any txt
> files with any perf data listed.  I mentioned a lot of gibberish
> earlier but problem my biggest advice would be to add more benchmarks
> and look at your benchmarks again and also get real world usage data.

yes, 
at least i should add the benchmark result in the javadoc. 

regards, 
Rémi 

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to