Странные результаты тестов OpenHFT Chronicle-Values - PullRequest
0 голосов
/ 31 октября 2019

Итак, я пытаюсь провести тестирование, просматривая 3_000_000 точечных элементов и выполняя простую операцию сложения для каждой точки. Точное сравнение между этими точками, объявленными обычным способом Java в качестве класса Point, и созданием Point [] и использованием OpenHFT Chronicle-Values ​​для создания уплощенной структуры памяти точек. Вот код:

    public interface Point {
    double getX();
    void setX(double x);

    double getY();
    void setY(double y);

    static int sizeOf() { return 16; }
}

    public interface PointArray {
    @Array(length=3_000_000)
    Point getPointAt(int index);
    void setPointAt(int index, Point point);
}

    public class PointImplForComp {

    public PointImplForComp(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double x;
    public double y;
}


    package benchmarks;

import net.openhft.chronicle.bytes.Byteable;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.values.Values;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import values.Point;
import values.PointArray;
import values.PointImplForComp;

public class Benchmarks {

    @Benchmark
    @Fork(value = 1, warmups = 5)
    public static void sumPointsNative() {
        PointArray pointArray = generateOffHeapValueArray();

        double sum = 0;
        for (int i = 0 ; i < 3_000_000; i++) {
            sum = pointArray.getPointAt(i).getX() + pointArray.getPointAt(i).getY();
        }

    }

    @Benchmark
    @Fork(value = 1, warmups = 5)
    public static void sumPointsVM() {
        PointImplForComp[] pointImplForComps = generateVMPointArray();

        double sum = 0;
        for (int i = 0 ; i < 3_000_000; i++) {
            sum = pointImplForComps[i].x + pointImplForComps[i].y;
        }
    }

    private static PointArray generateOffHeapValueArray() {
        final int nrOfElements = 3_000_000;
        byte[] layoutContainer = new byte[nrOfElements * Point.sizeOf()];
        PointArray offHeapPointArray = Values.newNativeReference(PointArray.class);
        ((Byteable) offHeapPointArray).bytesStore(BytesStore.wrap(layoutContainer), 0, layoutContainer.length);

        for (int i = 0; i < nrOfElements; i++) {
            offHeapPointArray.setPointAt(i, generatePointValue(i, i, layoutContainer, i * Point.sizeOf(), Point.sizeOf())); // each point has 16 bytes so the offset starts from 0_16; 16_32 (1 * 16_1* 16 + 16)
        }

        return offHeapPointArray;
    }

    // use the array layout
    private static Point generatePointValue(long x, long y, byte[] layoutContainer, int offset, int length) {
        Point offHeapPoint = Values.newNativeReference(Point.class);
        ((Byteable) offHeapPoint).bytesStore(BytesStore.wrap(layoutContainer), offset, length);
        offHeapPoint.setX(x);
        offHeapPoint.setY(y);

        return offHeapPoint;
    }


    private static PointImplForComp[] generateVMPointArray() {
        final int nrOfElements = 3_000_000;
        PointImplForComp[] points = new PointImplForComp[nrOfElements];

        for (int i = 0; i < nrOfElements; i++) {
            points[i] = new PointImplForComp(i, i);
        }

        return points;
    }
}

Результаты показывают, что я получаю на 30_000 больше операций в секунду от функции sumPointsVM (), что оказалось не таким, как я ожидал, по меньшей мере. Я уверен, что не правильно использую значения хроники, но кто-то может дать мне кивок в правильном направлении? Примеры скудны и API не интуитивно понятен. Я даже не знаю, почему я не могу найти метод для освобождения созданной собственной памяти или это действительно собственная память, потому что я использую экземпляр Values.newNAtiveReference, но также использую вспомогательный байт [], а не адрес памяти вне кучи.

...