/* * Copyright (c) 2004-2008 QOS.ch * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.slf4j.helpers; import junit.framework.AssertionFailedError; /** * BogoPerf is used to check that the time required to perform a certain * operation does not deteriorate over time. BogoPerf adjusts to the CPU speed * and capabilities of the host. * * @author Ceki Gülcü * */ public class BogoPerf { private static long NANOS_IN_ONE_SECOND = 1000 * 1000 * 1000; private static int INITIAL_N = 1000; private static int LAST_N = 100; private static int SLACK_FACTOR = 3; static { // let the JIT warm up computeBogoIPS(INITIAL_N); double bogo_ips = computeBogoIPS(INITIAL_N); System.out.println("Host runs at " + bogo_ips + " BIPS"); } /** * Compute bogoInstructions per second * <p> * on a 3.2 Ghz Pentium D CPU (around 2007), we obtain about 9'000 bogoIPS. * * @param N * number of bogoInstructions to average over in order to * compute the result * @return bogo Instructions Per Second */ private static double computeBogoIPS(int N) { long begin = System.nanoTime(); for (int i = 0; i < N; i++) { bogoInstruction(); } long end = System.nanoTime(); // duration double D = end - begin; // average duration per instruction double avgDPIS = D / N; // System.out.println(D + " nanos for " + N + " instructions"); // System.out.println(avgD + " nanos per instruction"); double bogoIPS = NANOS_IN_ONE_SECOND / avgDPIS; // System.out.println(bogoIPS + " bogoIPS"); return bogoIPS; } private static void bogoInstruction() { // use our own random number generator, independent of the host JDK MyRandom myRandom = new MyRandom(100); int len = 150; int[] intArray = new int[len]; for (int i = 0; i < len; i++) { intArray[i] = myRandom.nextInt(); } // use our own sort algorithm, independent of the host JDK BubbleSort.sort(intArray); } /** * Computed the BogoIPS for this host CPU. * * @return */ public static double currentBIPS() { return computeBogoIPS(LAST_N); } static double min(double a, double b) { return (a <= b) ? a : b; } /** * Assertion used for values that <b>decrease</b> with faster CPUs, typically * the time (duration) needed to perform a task. * * @param currentDuration * @param referenceDuration * @param referenceBIPS * @throws AssertionFailedError */ public static void assertDuration(double currentDuration, long referenceDuration, double referenceBIPS) throws AssertionFailedError { double ajustedDuration = adjustExpectedDuration(referenceDuration, referenceBIPS); if (currentDuration > ajustedDuration * SLACK_FACTOR) { throw new AssertionFailedError("current duration " + currentDuration + " exceeded expected " + ajustedDuration + " (adjusted reference), " + referenceDuration + " (raw reference)"); } } /** * Assertion used for values that <b>increase<b> with faster CPUs, typically * the number of operations accomplished per unit of time. * * @param currentPerformance * @param referencePerformance * @param referenceBIPS * @throws AssertionFailedError */ public static void assertPerformance(double currentPerformance, long referencePerformance, double referenceBIPS) throws AssertionFailedError { double ajustedPerf = adjustExpectedPerformance(referencePerformance, referenceBIPS); if (currentPerformance * SLACK_FACTOR < ajustedPerf) { throw new AssertionFailedError(currentPerformance + " below expected " + ajustedPerf + " (adjusted), " + referencePerformance + " (raw)"); } } private static double adjustExpectedPerformance(long referenceDuration, double referenceBIPS) { double currentBIPS = currentBIPS(); return referenceDuration * (currentBIPS / referenceBIPS); } private static double adjustExpectedDuration(long referenceDuration, double referenceBIPS) { double currentBIPS = currentBIPS(); System.out.println("currentBIPS=" + currentBIPS + " BIPS"); return referenceDuration * (referenceBIPS / currentBIPS); } }