VarHandle instance methods performance
Roger Riggs
Roger.Riggs at oracle.com
Thu Apr 25 13:07:04 UTC 2019
Hi Frank,
These performance measurements would be good to add as JMH tests in
open/test/micro...
Thanks, Roger
On 04/24/2019 05:51 AM, Frank Yuan wrote:
> Hi Aleksey
>
> I happened to see the performance to access a field by VarHandle API is much worse than the native access.
>
> I tested the following situations:
> 1. reading a volatile field directly
> 2. calling getVolatile against this volatile field
> 3. calling getVolatile against another non-volatile field
>
> As my expectation, Situation 2 has similar performance with situation 3, but both of them have 100 times of situation 1 execution time in my test.
>
> I think it should be due to some overhead, and it doesn't violate the JEP 193 performance requirement. But I still can't figure out why it's so slow after runtime compiling? Hope you can give me some point. Thanks!
>
>
> My test code is as below:
>
> import java.lang.invoke.MethodHandles;
> import java.lang.invoke.VarHandle;
> import java.lang.management.ManagementFactory;
> import java.lang.management.ThreadMXBean;
>
> public class Test5 {
>
> static final int iter_num = 100000000;
> private volatile int vf = 1;
> private int f = 1;
> final VarHandle vhf;
> final VarHandle vhvf;
> final ThreadMXBean threadMXBean;
>
> public Test5 () throws Exception {
> vhf = MethodHandles.lookup().findVarHandle(
> Test5.class, "f", int.class);
> vhvf = MethodHandles.lookup().findVarHandle(
> Test5.class, "vf", int.class);
>
> threadMXBean = ManagementFactory.getThreadMXBean();
>
> //System.out.println(threadMXBean.isCurrentThreadCpuTimeSupported());
> //System.out.println(threadMXBean.isThreadCpuTimeEnabled());
> }
>
>
> public void measGetVolatileField() {
> int tmpProgress = 0;
> long startCpu = threadMXBean.getCurrentThreadCpuTime();
> long startUser = threadMXBean.getCurrentThreadUserTime();
> for (int i = 0; i < iter_num; ++i) {
> tmpProgress += vf;
> }
>
> long endCpu = threadMXBean.getCurrentThreadCpuTime();
> long endUser = threadMXBean.getCurrentThreadUserTime();
>
> long durCpu = endCpu -startCpu;
> long durUser = endUser - startUser;
> System.out.println("measGetVolatileField");
> System.out.println("cpu time: " + durCpu);
> System.out.println("user time: " + durUser);
> System.out.println(tmpProgress);
> }
>
>
> public void measGetVolatileFieldByVHWithVolatile() {
> int tmpProgress = 0;
> long startCpu = threadMXBean.getCurrentThreadCpuTime();
> long startUser = threadMXBean.getCurrentThreadUserTime();
> for (int i = 0; i < iter_num; ++i) {
> tmpProgress += (int) vhvf.getVolatile(this);
> }
>
> long endCpu = threadMXBean.getCurrentThreadCpuTime();
> long endUser = threadMXBean.getCurrentThreadUserTime();
>
> long durCpu = endCpu -startCpu;
> long durUser = endUser - startUser;
> System.out.println("measGetVolatileFieldByVHWithVolatile");
> System.out.println("cpu time: " + durCpu);
> System.out.println("user time: " + durUser);
> System.out.println(tmpProgress);
> }
>
>
> public void measGetFieldByVHWithVolatile() {
> int tmpProgress = 0;
> long startCpu = threadMXBean.getCurrentThreadCpuTime();
> long startUser = threadMXBean.getCurrentThreadUserTime();
> for (int i = 0; i < iter_num; ++i) {
> tmpProgress += (int) vhf.getVolatile(this);
> }
>
> long endCpu = threadMXBean.getCurrentThreadCpuTime();
> long endUser = threadMXBean.getCurrentThreadUserTime();
>
> long durCpu = endCpu -startCpu;
> long durUser = endUser - startUser;
> System.out.println("measGetFieldByVHWithVolatile");
> System.out.println("cpu time: " + durCpu);
> System.out.println("user time: " + durUser);
> System.out.println(tmpProgress);
> }
>
> public static void main(String[] args) throws Exception {
>
> for (int i = 0; i < 5; i++) {
> Test5 test = new Test5 ();
>
>
> Thread threadA = new Thread(() -> test.measGetVolatileField());
> Thread threadB = new Thread(() -> test.measGetVolatileFieldByVHWithVolatile());
> Thread threadC = new Thread(() -> test.measGetFieldByVHWithVolatile());
>
> threadA.start();
> threadA.join();
>
> threadB.start();
> threadB.join();
>
> threadC.start();
> threadC.join();
>
> }
>
> }
>
> }
>
>
More information about the core-libs-dev
mailing list