Author: kkolinko Date: Fri Jun 19 12:27:08 2009 New Revision: 786477 URL: http://svn.apache.org/viewvc?rev=786477&view=rev Log: Rewrote the benchmarks, to allow more than 2 different implementations to be compared.
Modified: tomcat/trunk/test/org/apache/catalina/valves/Benchmarks.java Modified: tomcat/trunk/test/org/apache/catalina/valves/Benchmarks.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/valves/Benchmarks.java?rev=786477&r1=786476&r2=786477&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/valves/Benchmarks.java (original) +++ tomcat/trunk/test/org/apache/catalina/valves/Benchmarks.java Fri Jun 19 12:27:08 2009 @@ -31,23 +31,26 @@ public class Benchmarks extends TestCase { public void testAccessLogGetDate() throws Exception { // Is it better to use a sync or a thread local here? - BenchmarkTest getDate = new GetDateBenchmarkTest(); - getDate.doTest(5); + BenchmarkTest benchmark = new BenchmarkTest(); + Runnable[] tests = new Runnable[] { new GetDateBenchmarkTest_Sync(), + new GetDateBenchmarkTest_Local() }; + benchmark.doTest(5, tests); } - private static class GetDateBenchmarkTest extends BenchmarkTest { + private static class GetDateBenchmarkTest_Sync implements Runnable { + + public String toString() { + return "Syncs"; + } + private volatile long currentMillis = 0; private volatile Date currentDate = null; - private ThreadLocal<Long> currentMillisLocal = new ThreadLocal<Long>() { - protected Long initialValue() { - return Long.valueOf(0); - } - }; - - private ThreadLocal<Date> currentDateLocal = new ThreadLocal<Date>(); + public void run() { + getCurrentDate(); + } - public Object doSync() { + public Date getCurrentDate() { long systime = System.currentTimeMillis(); if ((systime - currentMillis) > 1000) { synchronized (this) { @@ -57,67 +60,83 @@ } } } - return currentDate; + return currentDate; + } + } + + private static class GetDateBenchmarkTest_Local implements Runnable { + + public String toString() { + return "ThreadLocals"; + } + + private ThreadLocal<Long> currentMillisLocal = new ThreadLocal<Long>() { + protected Long initialValue() { + return Long.valueOf(0); + } + }; + + private ThreadLocal<Date> currentDateLocal = new ThreadLocal<Date>(); + + public void run() { + getCurrentDate(); } - - public Object doLocal() { + + public Date getCurrentDate() { long systime = System.currentTimeMillis(); if ((systime - currentMillisLocal.get().longValue()) > 1000) { currentDateLocal.set(new Date(systime)); currentMillisLocal.set(Long.valueOf(systime)); } - return currentDateLocal.get(); + return currentDateLocal.get(); } } - public void testAccessLogTimeDateElement() throws Exception { // Is it better to use a sync or a thread local here? - BenchmarkTest timeDateElement = new TimeDateElementBenchmarkTest(); - timeDateElement.doTest(5); + BenchmarkTest benchmark = new BenchmarkTest(); + Runnable[] tests = new Runnable[] { + new TimeDateElementBenchmarkTest_Sync(), + new TimeDateElementBenchmarkTest_Local() }; + benchmark.doTest(5, tests); } - private static class TimeDateElementBenchmarkTest extends BenchmarkTest { + private static abstract class TimeDateElementBenchmarkTestBase { + protected static final String months[] = { "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + protected String lookup(String month) { + int index; + try { + index = Integer.parseInt(month) - 1; + } catch (Throwable t) { + index = 0; // Can not happen, in theory + } + return (months[index]); + } + } + + private static class TimeDateElementBenchmarkTest_Sync extends + TimeDateElementBenchmarkTestBase implements Runnable { + + public String toString() { + return "Syncs"; + } + private volatile long currentMillis = 0; private volatile Date currentDate = null; private String currentDateString = null; private SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); private SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); private SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); - private SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss"); - - private ThreadLocal<Long> currentMillisLocal = new ThreadLocal<Long>() { - protected Long initialValue() { - return Long.valueOf(0); - } - }; - private ThreadLocal<Date> currentDateLocal = new ThreadLocal<Date>(); - private ThreadLocal<SimpleDateFormat> dayFormatterLocal = - new ThreadLocal<SimpleDateFormat>() { - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("dd"); - } - }; - private ThreadLocal<SimpleDateFormat> monthFormatterLocal = - new ThreadLocal<SimpleDateFormat>() { - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("MM"); - } - }; - private ThreadLocal<SimpleDateFormat> yearFormatterLocal = - new ThreadLocal<SimpleDateFormat>() { - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("yyyy"); - } - }; - private ThreadLocal<SimpleDateFormat> timeFormatterLocal = - new ThreadLocal<SimpleDateFormat>() { - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("hh:mm:ss"); - } - }; - - public Object doSync() { + private SimpleDateFormat timeFormatter = new SimpleDateFormat( + "hh:mm:ss"); + + public void run() { + printDate(); + } + + public StringBuffer printDate() { StringBuffer buf = new StringBuffer(); Date date = getDateSync(); if (currentDate != date) { @@ -141,21 +160,7 @@ buf.append(currentDateString); return buf; } - - protected static final String months[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - private String lookup(String month) { - int index; - try { - index = Integer.parseInt(month) - 1; - } catch (Throwable t) { - index = 0; // Can not happen, in theory - } - return (months[index]); - } - private Date getDateSync() { long systime = System.currentTimeMillis(); if ((systime - currentMillis) > 1000) { @@ -166,10 +171,52 @@ } } } - return currentDate; + return currentDate; + } + } + + private static class TimeDateElementBenchmarkTest_Local extends + TimeDateElementBenchmarkTestBase implements Runnable { + + public String toString() { + return "ThreadLocals"; + } + + private volatile Date currentDate = null; + private String currentDateString = null; + + private ThreadLocal<Long> currentMillisLocal = new ThreadLocal<Long>() { + protected Long initialValue() { + return Long.valueOf(0); + } + }; + private ThreadLocal<Date> currentDateLocal = new ThreadLocal<Date>(); + private ThreadLocal<SimpleDateFormat> dayFormatterLocal = new ThreadLocal<SimpleDateFormat>() { + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("dd"); + } + }; + private ThreadLocal<SimpleDateFormat> monthFormatterLocal = new ThreadLocal<SimpleDateFormat>() { + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("MM"); + } + }; + private ThreadLocal<SimpleDateFormat> yearFormatterLocal = new ThreadLocal<SimpleDateFormat>() { + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy"); + } + }; + private ThreadLocal<SimpleDateFormat> timeFormatterLocal = new ThreadLocal<SimpleDateFormat>() { + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("hh:mm:ss"); + } + }; + + public void run() { + printDate(); } - - public Object doLocal() { + + public StringBuffer printDate() { StringBuffer buf = new StringBuffer(); Date date = getDateLocal(); if (currentDate != date) { @@ -189,35 +236,32 @@ buf.append(currentDateString); return buf; } - + private Date getDateLocal() { long systime = System.currentTimeMillis(); if ((systime - currentMillisLocal.get().longValue()) > 1000) { currentDateLocal.set(new Date(systime)); currentMillisLocal.set(Long.valueOf(systime)); } - return currentDateLocal.get(); + return currentDateLocal.get(); } } - - private static abstract class BenchmarkTest { - public abstract Object doSync(); - public abstract Object doLocal(); - - public void doTest(int threadCount) throws Exception { - for (int iterations = 1000000; iterations < 10000001; iterations+=1000000) { - doTestInternal(threadCount, iterations, true); - doTestInternal(threadCount, iterations, false); + private static class BenchmarkTest { + public void doTest(int threadCount, Runnable[] tests) throws Exception { + for (int iterations = 1000000; iterations < 10000001; iterations += 1000000) { + for (int i = 0; i < tests.length; i++) { + doTestInternal(threadCount, iterations, tests[i]); + } } } - + private void doTestInternal(int threadCount, int iterations, - boolean useSyncs) throws Exception { + Runnable test) throws Exception { long start = System.currentTimeMillis(); Thread[] threads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { - threads[i] = new Thread(new TestThread(iterations, useSyncs, this)); + threads[i] = new Thread(new TestThread(iterations, test)); } for (int i = 0; i < threadCount; i++) { threads[i].start(); @@ -226,35 +270,26 @@ threads[i].join(); } long end = System.currentTimeMillis(); - - System.out.println(this.getClass().getName() + ": " + threadCount + - " threads and " + iterations + " iterations " + - (useSyncs?"using Syncs":"using ThreadLocals") + - " took " + (end-start) + "ms"); - } + System.out.println(test.getClass().getName() + ": " + threadCount + + " threads and " + iterations + " iterations using " + + test + " took " + (end - start) + "ms"); + } } private static class TestThread implements Runnable { private int count; - private boolean useSync; - private BenchmarkTest benchmarkTest; - - public TestThread(int count, boolean useSync, BenchmarkTest benchmarkTest) { + private Runnable test; + + public TestThread(int count, Runnable test) { this.count = count; - this.useSync = useSync; - this.benchmarkTest = benchmarkTest; + this.test = test; } - + public void run() { for (int i = 0; i < count; i++) { - if (useSync) { - benchmarkTest.doSync(); - } else { - benchmarkTest.doLocal(); - } + test.run(); } } - } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org