Setting a value to a MemorySegment slower with VarHandle

Daniele Guiducci daniele.guiducci at gmail.com
Fri Oct 28 21:59:41 UTC 2022


Hello,

I'm running some tests comparing the performance of the various methods
available to set a value in a MemorySegment.

Based on a simple benchmark I wrote, VarHandle seems to be the slowest one,
which is odd to me.

This is the output of the benchmark:

   - Manual offset set; Total time 147
   - VarHandle; Total time 3197
   - Method Handle; Total time 767

I'm testing this from a MacOS Air M2 (arm chip). I also ran other tests
trying to warm up the virtual machine but I didn't get much improvements.

And this is the code. I didn't use microbenchmarking but the result
wouldn't change:
public static void main(String[] args) throws Throwable {
        long elementCount = 200_000_000;
        var testFile = Path.of("test.data");
        FileChannel fc = FileChannel.open(testFile,
                StandardOpenOption.CREATE,
                StandardOpenOption.READ,
                StandardOpenOption.WRITE
        );
        var segment = fc.map(FileChannel.MapMode.READ_WRITE, 0,
elementCount * Integer.BYTES, MemorySession.global());

        MemoryLayout memoryLayout = MemoryLayout.sequenceLayout(
                elementCount, ValueLayout.JAVA_INT.withName("counter")
        );

        VarHandle varHandle =
memoryLayout.varHandle(MemoryLayout.PathElement.sequenceElement());
        var arrayMethodHandle =
memoryLayout.byteOffsetHandle(MemoryLayout.PathElement.sequenceElement());


        // Init file Manually
        for (int i = 0; i < elementCount; i++) {
            segment.set(ValueLayout.JAVA_INT, i * 4L, 99);
        }

        long startTime;


        startTime = System.currentTimeMillis();
        for (int i = 0; i < elementCount; i++) {
            segment.set(ValueLayout.JAVA_INT, i * Integer.BYTES, 33);
        }
        System.out.println("Manual offset set; Total time " +
(System.currentTimeMillis() - startTime));


        startTime = System.currentTimeMillis();
        for (int i = 0; i < elementCount; i++) {
            varHandle.set(segment, (long) i, 10);
        }
        System.out.println("VarHandle; Total time " +
(System.currentTimeMillis() - startTime));


        startTime = System.currentTimeMillis();
        for (int i = 0; i < elementCount; i++) {
            // User method handle to calculate offset
            long offset = (long) arrayMethodHandle.invokeExact((long) i);
            segment.set(ValueLayout.JAVA_INT, offset, 10);
        }
        System.out.println("Method Handle; Total time " +
(System.currentTimeMillis() - startTime));

        fc.close();
        Files.delete(testFile);
    }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20221028/4e361caa/attachment.htm>


More information about the panama-dev mailing list