import java.io.StringWriter; public class FakeLog { private static final int NUM_ITERATIONS = 1000000000; private static boolean LOG_ENABLED; private final boolean enableLog; private FakeLog(boolean enableLog) { this.enableLog = enableLog; } /** * Basic log method, as you would find on most logging APIs. Typically any data that is to be included * in the log statement will string concatenated into the message string before this call is made. */ public void log(String message) { if(!enableLog) { return; } System.out.println(message); } /** * This is for testing the effect of logging without checking whether the log is enabled first, but * passing in a list of objects so as to avoid calling toString() on them if it is unnecessary * (as will happen with string concatenation in log(String)) */ public void logVarArgs(String messageFormat, Object... args) { if(!enableLog) { return; } System.out.println(String.format(messageFormat, args)); } /** * This is for testing the effect of passing a fixed set of parameters, as opposed to a varargs * array. */ public void logWithFixedParamCount(String messageFormat, Object a, Object b) { if(!enableLog) { return; } System.out.println(String.format(messageFormat, a, b)); } public boolean isLoggable() { return enableLog; } public static void main(String[] args) { LOG_ENABLED = false; // testLogging_stringConcat_noCheck(); testLogging_stringConcat_ifCheck_isLoggable(); testLogging_stringConcat_ifCheck_constantAndIsLoggable(); testLogging_fixedArgs_noCheck(); testLogging_varArgs_noCheck(); } private static void testLogging_stringConcat_ifCheck_isLoggable() { FakeLog log = new FakeLog(false); long startTime = System.nanoTime(); for(int i=0; i < NUM_ITERATIONS; i++) { if(log.isLoggable()) { log.log("Testing the logging, a=" + new BigToStringGenerator() + ", i=" + i); } } long endTime = System.nanoTime(); printResult("testLogging_stringConcat_ifCheck_isLoggable()", endTime, startTime); } private static void testLogging_stringConcat_ifCheck_constantAndIsLoggable() { FakeLog log = new FakeLog(false); long startTime = System.nanoTime(); for(int i=0; i < NUM_ITERATIONS; i++) { if(LOG_ENABLED && log.isLoggable()) { log.log("Testing the logging, a=" + new BigToStringGenerator() + ", i=" + i); } } long endTime = System.nanoTime(); printResult("testLogging_stringConcat_ifCheck_constantAndIsLoggable", endTime, startTime); } private static void testLogging_stringConcat_noCheck() { FakeLog log = new FakeLog(false); long startTime = System.nanoTime(); for(int i=0; i < NUM_ITERATIONS; i++) { log.log("Testing the logging, a=" + new BigToStringGenerator() + ", i=" + i); } long endTime = System.nanoTime(); printResult("testLogging_stringConcat_noCheck", endTime, startTime); } private static void testLogging_varArgs_noCheck() { FakeLog log = new FakeLog(false); long startTime = System.nanoTime(); for(int i=0; i < NUM_ITERATIONS; i++) { log.logVarArgs("Testing the logging, a=%s, i=%d", new BigToStringGenerator(), i); } long endTime = System.nanoTime(); printResult("testLogging_varArgs_noCheck", endTime, startTime); } private static void testLogging_fixedArgs_noCheck() { FakeLog log = new FakeLog(false); long startTime = System.nanoTime(); for(int i=0; i < NUM_ITERATIONS; i++) { log.logWithFixedParamCount("Testing the logging, a=%s, i=%d", new BigToStringGenerator(), i); } long endTime = System.nanoTime(); printResult("testLogging_fixedArgs_noCheck", endTime, startTime); } private static void printResult(String testName, long endTimeInNs, long startTimeInNs) { double totalTime = endTimeInNs - startTimeInNs; System.out.println("Time taken for " + testName + ": " + asMillisecondString(totalTime)); System.out.println("Cost per iteration: " + (totalTime / NUM_ITERATIONS) + "ns"); } private static String asMillisecondString(double durationInNanos) { return Double.toString(durationInNanos / 1000000.0) + "ms"; } public static class BigToStringGenerator { @Override public String toString() { StringWriter writer = new StringWriter(); for(int i=0; i < 10; i++) { writer.append(Double.toString(Math.random())); } return writer.toString(); } } }