Package tm

Source Code of tm.TimeVsMemory

/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 tm;

import com.carrotsearch.hppc.*;
import com.carrotsearch.hppc.procedures.*;
import com.gs.collections.api.map.primitive.*;
import com.gs.collections.api.tuple.primitive.*;
import com.gs.collections.impl.map.mutable.primitive.*;
import gnu.trove.iterator.*;
import gnu.trove.map.*;
import gnu.trove.map.hash.*;
import gnu.trove.procedure.*;
import it.unimi.dsi.fastutil.objects.*;
import net.openhft.bench.DimensionedJmh;
import net.openhft.koloboke.collect.hash.*;
import net.openhft.koloboke.collect.map.*;
import net.openhft.koloboke.collect.map.hash.*;
import org.apache.mahout.math.map.*;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.CommandLineOptionException;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.stream.IntStream;

import static java.lang.Integer.parseInt;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.IntStream.iterate;
import static java.util.stream.IntStream.range;
import static org.openjdk.jol.info.GraphLayout.parseInstance;


@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Threads(1)
@Fork(1)
@Warmup(iterations = 5, time = 1, timeUnit = SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = SECONDS)
public class TimeVsMemory {
    static final int MIN_SIZE = 1000, MAX_SIZE = 10_000_000;
    static final int SIZE_STEPS = 10;

    static IntStream sizes;
    static {
        double sizeRatio = MAX_SIZE * 1.0 / MIN_SIZE;
        double step = Math.pow(sizeRatio, 1.0 / (SIZE_STEPS - 1));
        sizes = iterate(MIN_SIZE, s -> (int) (s * step)).limit(SIZE_STEPS);
    }

    static final IntStream loadLevels = range(1, 10);

    static final int SIZE = Integer.getInteger("size", MIN_SIZE);
    static final int LOAD_LEVEL = Integer.getInteger("loadLevel", 5);

    static HashConfig config(int loadLevel) {
        switch (loadLevel) {
            case 1: return config(0.066, 0.1, 0.134, 2.0);
            case 2: return config(0.133, 0.2, 0.267, 2.0);
            case 3: return config(0.2, 0.3, 0.4, 2.0);
            case 4: return config(0.266, 0.4, 0.534, 2.0);
            case 5: return config(0.33, 0.5, 0.67, 2.0);
            case 6: return config(0.4, 0.6, 0.8, 2.0);
            case 7: return config(0.466, 0.7, 0.934, 2.0);
            case 8: return config(0.64, 0.8, 0.96, 1.5);
            case 9: return config(0.79, 0.9, 0.99, 1.25);
            default: throw new AssertionError();
        }
    }

    private static HashConfig config(double minLoad, double targetLoad, double maxLoad,
            double growFactor) {
        HashConfig config = HashConfig.getDefault().withGrowFactor(growFactor);
        if (minLoad < config.getMinLoad()) {
            return config.withMinLoad(minLoad).withTargetLoad(targetLoad).withMaxLoad(maxLoad);
        } else {
            return config.withMaxLoad(maxLoad).withTargetLoad(targetLoad).withMinLoad(minLoad);
        }
    }

    /* with char|byte|int|long key */

    static class StdCharCharMap extends HashMap<Character, Character> {
        StdCharCharMap(int initialCapacity, float loadFactor) {
            super(initialCapacity, loadFactor);
        }
    }

    private static StdCharCharMap stdCharCharMap(int loadLevel, int size) {
        double loadFactor = 0.1 * loadLevel;
        int initialCapacity = (int) (size / loadFactor) + 1;
        return new StdCharCharMap(initialCapacity, (float) loadFactor);
    }

    private static char addValue(StdCharCharMap map, char key, char value) {
        return map.merge(key, value, (v1, v2) -> (char) (v1 + v2));
    }

    private static long iter(StdCharCharMap map) {
        long dummy = 0L;
        for (Map.Entry<Character, Character> entry : map.entrySet()) {
            dummy ^= entry.getKey() + entry.getValue();
        }
        return dummy;
    }

    private static net.openhft.koloboke.collect.map.CharCharMap kolobokeCharCharMap(
            int loadLevel, int size) {
        HashCharCharMapFactory factory = HashCharCharMaps.getDefaultFactory();
        factory = factory.withHashConfig(config(loadLevel));
        return factory.newUpdatableMap(size);
    }

    private static char addValue(net.openhft.koloboke.collect.map.CharCharMap map,
            char key, char value) {
        return map.addValue(key, value);
    }

    private static long iter(net.openhft.koloboke.collect.map.CharCharMap map) {
        long dummy = 0L;
        for (CharCharCursor cur = map.cursor(); cur.moveNext();) {
            dummy ^= cur.key() + cur.value();
        }
        return dummy;
    }

    private static TCharCharMap troveCharCharMap(int loadLevel, int size) {
        double loadFactor = 0.1 * loadLevel;
        return new TCharCharHashMap(size, (float) loadFactor);
    }

    private static char addValue(TCharCharMap map, char key, char value) {
        return map.adjustOrPutValue(key, value, value);
    }

    private static long iter(TCharCharMap map) {
        long dummy = 0L;
        for (TCharCharIterator it = map.iterator(); it.hasNext(); ) {
            it.advance();
            dummy ^= it.key() + it.value();
        }
        return dummy;
    }

    private static com.carrotsearch.hppc.CharCharMap hppcCharCharMap(int loadLevel, int size) {
        double loadFactor = 0.1 * loadLevel;
        int initialCapacity = (int) (size / loadFactor) + 1;
        return new CharCharOpenHashMap(initialCapacity, (float) loadFactor);
    }

    private static char addValue(com.carrotsearch.hppc.CharCharMap map,
            char key, char value) {
        return map.addTo(key, value);
    }

    private static long iter(com.carrotsearch.hppc.CharCharMap map) {
        long dummy = 0L;
        for (com.carrotsearch.hppc.cursors.CharCharCursor cur : map) {
            dummy ^= cur.key + cur.value;
        }
        return dummy;
    }

    private static MutableCharCharMap gsCharCharMap(int loadLevel, int size) {
        double loadFactor = 0.1 * (loadLevel + 1);
        int initialCapacity = (int) (size / loadFactor);
        return new CharCharHashMap(initialCapacity);
    }

    private static char addValue(MutableCharCharMap map, char key, char value) {
        return map.addToValue(key, value);
    }

    private static long iter(MutableCharCharMap map) {
        long dummy = 0L;
        for (CharCharPair pair : map.keyValuesView()) {
            dummy ^= pair.getOne() + pair.getTwo();
        }
        return dummy;
    }

    private static it.unimi.dsi.fastutil.chars.Char2CharOpenHashMap fastutilCharCharMap(
            int loadLevel, int size) {
        return new it.unimi.dsi.fastutil.chars.Char2CharOpenHashMap(
                size, (float) (0.1 * loadLevel));
    }

    private static long iter(it.unimi.dsi.fastutil.chars.Char2CharOpenHashMap map) {
        long dummy = 0L;
        ObjectIterator<it.unimi.dsi.fastutil.chars.Char2CharMap.Entry> it = map.char2CharEntrySet()
                .fastIterator();
        while (it.hasNext()) {
            it.unimi.dsi.fastutil.chars.Char2CharMap.Entry entry = it.next();
            dummy ^= entry.getCharKey() + entry.getCharValue();
        }
        return dummy;
    }

    private static AbstractCharCharMap mahoutCharCharMap(int loadLevel, int size) {
        HashConfig config = config(loadLevel);
        int initialCapacity = (int) (size / config.getTargetLoad());
        return new OpenCharCharHashMap(initialCapacity, config.getMinLoad(), config.getMaxLoad());
    }

    private static char addValue(AbstractCharCharMap map, char key, char value) {
        return map.adjustOrPutValue(key, value, value);
    }

    /* define mapType */
    /* if Koloboke collections //net.openhft.koloboke.collect.map.CharCharMap
    // elif Trove collections //TCharCharMap
    // elif Hppc collections //com.carrotsearch.hppc.CharCharMap
    // elif Gs collections //MutableCharCharMap
    // elif Fastutil collections //it.unimi.dsi.fastutil.chars.Char2CharOpenHashMap
    // elif Mahout collections //AbstractCharCharMap
    // elif Std collections //StdCharCharMap
    // endif */
    /* enddefine */

    static class StdCharCharConsumer implements BiConsumer<Character, Character> {
        long dummy = 0L;
        @Override
        public void accept(Character a, Character b) {
            dummy ^= a + b;
        }

        public void forEach(StdCharCharMap map) {
            map.forEach(this);
        }
    }

    static class CharCharConsumer implements
            net.openhft.koloboke.function.CharCharConsumer, TCharCharProcedure, CharCharProcedure,
            com.gs.collections.api.block.procedure.primitive.CharCharProcedure {
        long dummy = 0L;

        @Override
        public void accept(char a, char b) {
            dummy ^= a + b;
        }

        /* with Koloboke|Hppc collections */
        public void forEach(/*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map) {
            map.forEach(this);
        }
        /* endwith */

        @Override
        public boolean execute(char a, char b) {
            dummy ^= a + b;
            return true;
        }

        public void forEach(TCharCharMap map) {
            map.forEachEntry(this);
        }

        @Override
        public void apply(char a, char b) {
            dummy ^= a + b;
        }

        @Override
        public void value(char a, char b) {
            dummy ^= a + b;
        }

        public void forEach(MutableCharCharMap map) {
            map.forEachKeyValue(this);
        }
    }

    static class MahoutCharCharConsumer
            implements org.apache.mahout.math.function.CharCharProcedure {
        long dummy = 0L;

        @Override
        public boolean apply(char a, char b) {
            dummy ^= a + b;
            return true;
        }

        public void forEach(AbstractCharCharMap map) {
            map.forEachPair(this);
        }
    }

    /* define consumerType */
    // if Std|Mahout collections //Koloboke// endif //CharCharConsumer
    /* enddefine */

    /* with Koloboke|Trove|Hppc|Gs|Fastutil|Mahout|Std collections */

    @State(Scope.Thread)
    public static class KolobokeCharCharMapState {
        Random r;
        char[] keys;
        /*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map;

        @Setup(Level.Trial)
        public void allocate() {
            r = ThreadLocalRandom.current();
            keys = new char[SIZE];
            map = kolobokeCharCharMap(LOAD_LEVEL, SIZE);
        }

        public void generateKeys() {
            for (int i = 0; i < keys.length; i++) {
                keys[i] = (char) r.nextLong();
            }
        }

        @TearDown(Level.Trial)
        public void recycle() {
            keys = null;
            map = null;
        }
    }

    public static class PutOpKolobokeCharCharMapState extends KolobokeCharCharMapState {
        @Setup(Level.Invocation)
        public void clearMap() {
            generateKeys();
            /* if !(Mahout collections) */map.clear();
            /* elif Mahout collections */map = kolobokeCharCharMap(LOAD_LEVEL, SIZE);
            /* endif */
        }
    }

    public static class QueryUpdateOpKolobokeCharCharMapState extends KolobokeCharCharMapState {
        @Setup(Level.Invocation)
        public void fillMap() {
            generateKeys();
            map.clear();
            for (char key : keys) {
                map.put(key, /* const key 1 */(char) 1/* endconst */);
            }
        }
    }

    @Benchmark
    public long putOp_kolobokeCollections_charKey(PutOpKolobokeCharCharMapState state) {
        char[] keys = state.keys;
        /*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map = state.map;
        for (char key : keys) {
            map.put(key, /* const key 1 */(char) 1/* endconst */);
        }
        return (long) map.size();
    }

    @Benchmark
    public long getOp_kolobokeCollections_charKey(QueryUpdateOpKolobokeCharCharMapState state) {
        char[] keys = state.keys;
        /*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map = state.map;
        long dummy = 0L;
        for (char key : keys) {
            dummy ^= (long) map.get(key);
        }
        return dummy;
    }

    /* if !(Fastutil collections) */
    @Benchmark
    public long addValueOp_kolobokeCollections_charKey(QueryUpdateOpKolobokeCharCharMapState state) {
        char[] keys = state.keys;
        /*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map = state.map;
        long dummy = 0L;
        for (char key : keys) {
            dummy ^= (long) addValue(map, key, /* const key 1 */(char) 1/* endconst */);
        }
        return dummy;
    }
    /* endif */

    /* if !(Fastutil collections) */
    @Benchmark
    public long forEachOp_kolobokeCollections_charKey(QueryUpdateOpKolobokeCharCharMapState state) {
        /*consumerType*/CharCharConsumer/**/ c = new /*consumerType*/CharCharConsumer/**/();
        c.forEach(state.map);
        return c.dummy;
    }
    /* endif */

    /* if !(Mahout collections) */
    @Benchmark
    public long iterOp_kolobokeCollections_charKey(QueryUpdateOpKolobokeCharCharMapState state) {
        return iter(state.map);
    }
    /* endif */

    /* endwith */
    /* endwith */

    public static void main(String[] args) throws RunnerException, CommandLineOptionException {
        if (Arrays.asList(args).contains("footprint")) {
            footPrintMain();
            return;
        }
        new DimensionedJmh(TimeVsMemory.class)
                .addArgDim("size", sizes.mapToObj(Integer::valueOf).toArray())
                .addArgDim("loadLevel", loadLevels.mapToObj(Integer::valueOf).toArray())
                .withGetOperationsPerInvocation(options -> parseInt(options.get("size")))
                .run(args);
    }

    static void footPrintMain() {
        int[] ss = sizes.toArray();
        loadLevels.forEach(loadLevel -> {
            /* with Koloboke|Trove|Hppc|Gs|Fastutil|Mahout|Std collections char|int key */
            /* if int key */
            Arrays.stream(ss).forEach(size -> {
                try {
                    /*mapType*/net.openhft.koloboke.collect.map.CharCharMap/**/ map =
                            kolobokeCharCharMap(loadLevel, size);
                    Random r = ThreadLocalRandom.current();
                    for (int i = 0; i < size; i++) {
                        map.put((char) r.nextLong(), /* const key 1 */
                                (char) 1/* endconst */);
                    }
                    double footPrint =
                            (parseInstance(map).totalSize() * 1.0 / size) / 8.0 - 1.0;
                    System.out.printf(Locale.US, "%d koloboke %.3f\n", loadLevel, footPrint);
                } catch (Throwable e) {
                }
            });
            /* endif */
            /* endwith */
        });
    }
}
TOP

Related Classes of tm.TimeVsMemory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.