Java tutorial
/* * Copyright 2009-2017 Aconex * * 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 io.pcp.parfait.benchmark; import static io.pcp.parfait.benchmark.BlockedMetricHelper.computeTotalBlockedCount; import static io.pcp.parfait.benchmark.BlockedMetricHelper.computeTotalBlockedTime; import static com.google.common.collect.Lists.newArrayList; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.net.UnknownHostException; import java.text.NumberFormat; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import io.pcp.parfait.DynamicMonitoringView; import io.pcp.parfait.MonitorableRegistry; import io.pcp.parfait.MonitoredCounter; import io.pcp.parfait.dxm.IdentifierSourceSet; import io.pcp.parfait.dxm.PcpMmvWriter; import io.pcp.parfait.pcp.EmptyTextSource; import io.pcp.parfait.pcp.MetricDescriptionTextSource; import io.pcp.parfait.pcp.MetricNameMapper; import io.pcp.parfait.pcp.PcpMonitorBridge; import com.google.common.base.Function; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; public class StandardMetricThroughPutBenchmark { private static final int CLUSTER_IDENTIFIER = 123; private final boolean startPcp; private final boolean usePerMetricLock; private final int numThreads; private final int iterations; private final int numCounters; private final ExecutorService executorService; public StandardMetricThroughPutBenchmark(int numThreads, int numCounters, int iterations, boolean startPcp, boolean usePerMetricLock) { this.numThreads = numThreads; this.numCounters = numCounters; this.iterations = iterations; this.startPcp = startPcp; this.usePerMetricLock = usePerMetricLock; this.executorService = Executors.newFixedThreadPool(this.numThreads); } private void runBenchmark() throws InterruptedException { long begin = System.currentTimeMillis(); MonitorableRegistry monitorableRegistry = new MonitorableRegistry(); List<MonitoredCounter> counters = createCounters(numCounters, monitorableRegistry); final PcpMmvWriter mmvWriter = new PcpMmvWriter( "parfait-microbenchmark-" + StandardMetricThroughPutBenchmark.class.getSimpleName() + ".mmv", IdentifierSourceSet.DEFAULT_SET); mmvWriter.setPerMetricLock(usePerMetricLock); mmvWriter.setClusterIdentifier(CLUSTER_IDENTIFIER); final PcpMonitorBridge pcpMonitorBridge = new PcpMonitorBridge(mmvWriter, MetricNameMapper.PASSTHROUGH_MAPPER, new MetricDescriptionTextSource(), new EmptyTextSource()); DynamicMonitoringView selfStartingMonitoringView = new DynamicMonitoringView(monitorableRegistry, pcpMonitorBridge, 2000); if (startPcp) { selfStartingMonitoringView.start(); } List<CounterIncrementer> counterIncrementers = executeBenchmark(numThreads, iterations, counters); if (startPcp) { selfStartingMonitoringView.stop(); } long timeTaken = System.currentTimeMillis() - begin; report(startPcp, counters, timeTaken, counterIncrementers); } private List<MonitoredCounter> createCounters(int numCounters, MonitorableRegistry registry) { List<MonitoredCounter> counters = newArrayList(); for (int i = 0; i < numCounters; i++) { counters.add(new MonitoredCounter("counter." + i, "Counter " + i, registry)); } return counters; } private List<BlockedMetricCollector> transformToListOfBlockedMetricCollectors( List<CounterIncrementer> counterIncrementers) { return Lists.transform(counterIncrementers, new Function<CounterIncrementer, BlockedMetricCollector>() { @Override public BlockedMetricCollector apply(CounterIncrementer input) { return input.getBlockedMetricCollector(); } }); } private void report(boolean startPcp, List<MonitoredCounter> counters, long timeTaken, List<CounterIncrementer> counterIncrementers) { long totalBlockedCount = computeTotalBlockedCount( transformToListOfBlockedMetricCollectors(counterIncrementers)); long totalBlockedTime = computeTotalBlockedTime( transformToListOfBlockedMetricCollectors(counterIncrementers)); double counterIncrements = computeTotalCounterIncrements(counters); double incrementRate = counterIncrements / ((double) timeTaken / 1000); NumberFormat numberFormat = NumberFormat.getNumberInstance(); numberFormat.setGroupingUsed(true); numberFormat.setMaximumFractionDigits(2); numberFormat.setMinimumFractionDigits(2); String incrementRateString = StringUtils.leftPad(numberFormat.format(incrementRate), 15); System.out.printf( "pcpStarted: %s\tperMetricLock: %s\tincrementRate(/sec): %s\t blockedCount: %d\t blockedTime: %d\n", startPcp, usePerMetricLock, incrementRateString, totalBlockedCount, totalBlockedTime); } private double computeTotalCounterIncrements(List<MonitoredCounter> counters) { double counterIncrements = 0; for (MonitoredCounter counter : counters) { counterIncrements += counter.get(); } return counterIncrements; } private List<CounterIncrementer> executeBenchmark(int numThreads, int iterations, List<MonitoredCounter> counters) throws InterruptedException { List<CounterIncrementer> counterIncrementers = newArrayList(); for (int i = 0; i < numThreads; i++) { CounterIncrementer counterIncrementer = new CounterIncrementer(counters, iterations); counterIncrementers.add(counterIncrementer); executorService.execute(counterIncrementer); } executorService.shutdown(); executorService.awaitTermination(1, TimeUnit.MINUTES); return counterIncrementers; } public static void main(String[] args) throws InterruptedException, UnknownHostException { int numThreads = args.length < 1 ? Runtime.getRuntime().availableProcessors() : Integer.valueOf(args[0]); int numCounters = 1000; int iterations = 10000; ReportHelper.environmentReportHeader(); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); System.out.printf("Thread Contention Supported: %s, Enabled by default: %s\n", threadMXBean.isThreadContentionMonitoringSupported(), threadMXBean.isThreadContentionMonitoringEnabled()); System.out.printf("numThreads: %d, numCounters=%d, iterations=%d\n", numThreads, numCounters, iterations); new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, false, false).runBenchmark(); new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, true, false).runBenchmark(); new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, true, true).runBenchmark(); // now do it all again reverse, in case there's any JVM warmup issues unfairly treating the first/last runs new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, true, true).runBenchmark(); new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, true, false).runBenchmark(); new StandardMetricThroughPutBenchmark(numThreads, numCounters, iterations, false, false).runBenchmark(); } }