/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.ignite.loadtests.h2indexing; import java.util.Iterator; import java.util.Map; import java.util.UUID; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicInteger; import org.apache.ignite.internal.util.snaptree.SnapTreeMap; /** * NavigableMaps PUT benchmark. */ public class GridTreeBenchmark { /** */ private static final int PUTS = 8000000; /** */ private static final int THREADS = 8; /** */ private static final int ITERATIONS = PUTS / THREADS; /** * Main method. * * @param args Command line args (not used). * @throws BrokenBarrierException If failed. * @throws InterruptedException If failed. */ public static void main(String... args) throws BrokenBarrierException, InterruptedException { doTestMaps(); } /** * @throws BrokenBarrierException If failed. * @throws InterruptedException If failed. */ private static void doTestAtomicInt() throws BrokenBarrierException, InterruptedException { final AtomicInteger[] cnts = new AtomicInteger[8]; for (int i = 0; i < cnts.length; i++) cnts[i] = new AtomicInteger(); final Thread[] ths = new Thread[THREADS]; final CyclicBarrier barrier = new CyclicBarrier(THREADS + 1); final AtomicInteger cnt = new AtomicInteger(); for (int i = 0; i < ths.length; i++) { ths[i] = new Thread(new Runnable() { @Override public void run() { int idx = cnt.getAndIncrement(); AtomicInteger x = cnts[idx % cnts.length]; try { barrier.await(); } catch (Exception e) { throw new IllegalStateException(e); } for (int i = 0; i < ITERATIONS; i++) x.incrementAndGet(); } }); ths[i].start(); } barrier.await(); long start = System.currentTimeMillis(); for (Thread t : ths) t.join(); long time = System.currentTimeMillis() - start; System.out.println(time); } /** * @throws BrokenBarrierException If failed. * @throws InterruptedException If failed. */ private static void doTestMaps() throws BrokenBarrierException, InterruptedException { final UUID[] data = generate(); @SuppressWarnings("unchecked") final Map<UUID, UUID>[] maps = new Map[4]; for (int i = 0; i < maps.length; i++) maps[i] = new SnapTreeMap<>(); final Thread[] ths = new Thread[THREADS]; final CyclicBarrier barrier = new CyclicBarrier(THREADS + 1); final AtomicInteger cnt = new AtomicInteger(); for (int i = 0; i < ths.length; i++) { ths[i] = new Thread(new Runnable() { @Override public void run() { int idx = cnt.getAndIncrement(); int off = idx * ITERATIONS; Map<UUID, UUID> map = maps[idx % maps.length]; try { barrier.await(); } catch (Exception e) { throw new IllegalStateException(e); } for (int i = 0; i < ITERATIONS; i++) { UUID id = data[off + i]; id = map.put(id, id); assert id == null; } } }); ths[i].start(); } System.out.println("Sleep"); Thread.sleep(10000); System.out.println("Go"); barrier.await(); long start = System.currentTimeMillis(); for (Thread t : ths) t.join(); long time = System.currentTimeMillis() - start; System.out.println(time); } /** * @throws BrokenBarrierException If failed. * @throws InterruptedException If failed. */ private static void doBenchmark() throws BrokenBarrierException, InterruptedException { int attemts = 20; int warmups = 10; long snapTreeTime = 0; long skipListTime = 0; for (int i = 0; i < attemts; i++) { ConcurrentNavigableMap<UUID, UUID> skipList = new ConcurrentSkipListMap<>(); ConcurrentNavigableMap<UUID, UUID> snapTree = new SnapTreeMap<>(); UUID[] ids = generate(); boolean warmup = i < warmups; snapTreeTime += doTest(snapTree, ids, warmup); skipListTime += doTest(skipList, ids, warmup); assert skipList.size() == snapTree.size(); Iterator<UUID> snapIt = snapTree.keySet().iterator(); Iterator<UUID> listIt = skipList.keySet().iterator(); for (int x = 0, len = skipList.size(); x < len; x++) assert snapIt.next() == listIt.next(); System.out.println(i + " =================="); } attemts -= warmups; System.out.println("Avg for GridSnapTreeMap: " + (snapTreeTime / attemts) + " ms"); System.out.println("Avg for ConcurrentSkipListMap: " + (skipListTime / attemts) + " ms"); } /** * @return UUIDs. */ private static UUID[] generate() { UUID[] ids = new UUID[ITERATIONS * THREADS]; for (int i = 0; i < ids.length; i++) ids[i] = UUID.randomUUID(); return ids; } /** * @param tree Tree. * @param data Data. * @param warmup Warmup. * @return Time. * @throws BrokenBarrierException If failed. * @throws InterruptedException If failed. */ private static long doTest(final ConcurrentNavigableMap<UUID, UUID> tree, final UUID[] data, boolean warmup) throws BrokenBarrierException, InterruptedException { Thread[] ths = new Thread[THREADS]; final CyclicBarrier barrier = new CyclicBarrier(THREADS + 1); final AtomicInteger cnt = new AtomicInteger(); for (int i = 0; i < ths.length; i++) { ths[i] = new Thread(new Runnable() { @Override public void run() { int off = cnt.getAndIncrement() * ITERATIONS; try { barrier.await(); } catch (Exception e) { throw new IllegalStateException(e); } for (int i = 0; i < ITERATIONS; i++) { UUID id = data[off + i]; id = tree.put(id, id); assert id == null; } } }); ths[i].start(); } barrier.await(); long start = System.currentTimeMillis(); for (Thread t : ths) t.join(); long time = System.currentTimeMillis() - start; if (!warmup) { System.out.println(tree.getClass().getSimpleName() + " " + time + " ms"); return time; } return 0; } }