All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazon.randomcutforest.StateMapperBenchmark Maven / Gradle / Ivy

There is a newer version: 4.2.0
Show newest version
/*
 * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazon.randomcutforest;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

import com.amazon.randomcutforest.config.Precision;
import com.amazon.randomcutforest.profilers.ObjectGraphSizeProfiler;
import com.amazon.randomcutforest.profilers.OutputSizeProfiler;
import com.amazon.randomcutforest.state.RandomCutForestMapper;
import com.amazon.randomcutforest.state.RandomCutForestState;
import com.amazon.randomcutforest.testutils.NormalMixtureTestData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

@Warmup(iterations = 2)
@Measurement(iterations = 5)
@Fork(value = 1)
@State(Scope.Benchmark)
public class StateMapperBenchmark {
    public static final int NUM_TRAIN_SAMPLES = 2048;
    public static final int NUM_TEST_SAMPLES = 50;

    @State(Scope.Thread)
    public static class BenchmarkState {
        @Param({ "10" })
        int dimensions;

        @Param({ "50" })
        int numberOfTrees;

        @Param({ "256" })
        int sampleSize;

        @Param({ "false", "true" })
        boolean saveTreeState;

        @Param({ "FLOAT_32", "FLOAT_64" })
        Precision precision;

        double[][] trainingData;
        double[][] testData;
        RandomCutForestState forestState;
        String json;
        byte[] protostuff;

        @Setup(Level.Trial)
        public void setUpData() {
            NormalMixtureTestData gen = new NormalMixtureTestData();
            trainingData = gen.generateTestData(NUM_TRAIN_SAMPLES, dimensions);
            testData = gen.generateTestData(NUM_TEST_SAMPLES, dimensions);
        }

        @Setup(Level.Invocation)
        public void setUpForest() throws JsonProcessingException {
            RandomCutForest forest = RandomCutForest.builder().compact(true).dimensions(dimensions)
                    .numberOfTrees(numberOfTrees).sampleSize(sampleSize).precision(precision)
                    .boundingBoxCacheFraction(0.0).build();

            for (int i = 0; i < NUM_TRAIN_SAMPLES; i++) {
                forest.update(trainingData[i]);
            }

            RandomCutForestMapper mapper = new RandomCutForestMapper();
            mapper.setSaveExecutorContextEnabled(true);
            mapper.setSaveTreeStateEnabled(saveTreeState);
            forestState = mapper.toState(forest);

            ObjectMapper jsonMapper = new ObjectMapper();
            json = jsonMapper.writeValueAsString(forestState);

            Schema schema = RuntimeSchema.getSchema(RandomCutForestState.class);
            LinkedBuffer buffer = LinkedBuffer.allocate(512);
            try {
                protostuff = ProtostuffIOUtil.toByteArray(forestState, schema, buffer);
            } finally {
                buffer.clear();
            }
        }
    }

    private RandomCutForest forest;
    private byte[] bytes;

    @TearDown(Level.Iteration)
    public void tearDown() {
        OutputSizeProfiler.setTestArray(bytes);
        ObjectGraphSizeProfiler.setObject(forest);
    }

    @Benchmark
    @OperationsPerInvocation(NUM_TEST_SAMPLES)
    public RandomCutForestState roundTripFromState(BenchmarkState state, Blackhole blackhole) {
        RandomCutForestState forestState = state.forestState;
        double[][] testData = state.testData;

        for (int i = 0; i < NUM_TEST_SAMPLES; i++) {
            RandomCutForestMapper mapper = new RandomCutForestMapper();
            mapper.setSaveExecutorContextEnabled(true);
            mapper.setSaveTreeStateEnabled(state.saveTreeState);
            forest = mapper.toModel(forestState);
            double score = forest.getAnomalyScore(testData[i]);
            blackhole.consume(score);
            forest.update(testData[i]);
            forestState = mapper.toState(forest);
        }

        return forestState;
    }

    @Benchmark
    @OperationsPerInvocation(NUM_TEST_SAMPLES)
    public String roundTripFromJson(BenchmarkState state, Blackhole blackhole) throws JsonProcessingException {
        String json = state.json;
        double[][] testData = state.testData;

        for (int i = 0; i < NUM_TEST_SAMPLES; i++) {
            ObjectMapper jsonMapper = new ObjectMapper();
            RandomCutForestState forestState = jsonMapper.readValue(json, RandomCutForestState.class);

            RandomCutForestMapper mapper = new RandomCutForestMapper();
            mapper.setSaveExecutorContextEnabled(true);
            mapper.setSaveTreeStateEnabled(state.saveTreeState);
            forest = mapper.toModel(forestState);

            double score = forest.getAnomalyScore(testData[i]);
            blackhole.consume(score);
            forest.update(testData[i]);
            json = jsonMapper.writeValueAsString(mapper.toState(forest));
        }

        bytes = json.getBytes();
        return json;
    }

    @Benchmark
    @OperationsPerInvocation(NUM_TEST_SAMPLES)
    public byte[] roundTripFromProtostuff(BenchmarkState state, Blackhole blackhole) {
        bytes = state.protostuff;
        double[][] testData = state.testData;

        for (int i = 0; i < NUM_TEST_SAMPLES; i++) {
            Schema schema = RuntimeSchema.getSchema(RandomCutForestState.class);
            RandomCutForestState forestState = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(bytes, forestState, schema);

            RandomCutForestMapper mapper = new RandomCutForestMapper();
            mapper.setSaveExecutorContextEnabled(true);
            mapper.setSaveTreeStateEnabled(state.saveTreeState);
            forest = mapper.toModel(forestState);

            double score = forest.getAnomalyScore(testData[i]);
            blackhole.consume(score);
            forest.update(testData[i]);
            forestState = mapper.toState(forest);

            LinkedBuffer buffer = LinkedBuffer.allocate(512);
            try {
                bytes = ProtostuffIOUtil.toByteArray(forestState, schema, buffer);
            } finally {
                buffer.clear();
            }
        }

        return bytes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy