Author: mircea.markus
Date: 2008-03-04 15:37:51 -0500 (Tue, 04 Mar 2008)
New Revision: 5385
Added:
core/trunk/src/test-perf/java/org/jboss/cache/LockMapPerformanceTest.java
Log:
test for benchmarking LockMap
Added: core/trunk/src/test-perf/java/org/jboss/cache/LockMapPerformanceTest.java
===================================================================
--- core/trunk/src/test-perf/java/org/jboss/cache/LockMapPerformanceTest.java
(rev 0)
+++ core/trunk/src/test-perf/java/org/jboss/cache/LockMapPerformanceTest.java 2008-03-04
20:37:51 UTC (rev 5385)
@@ -0,0 +1,212 @@
+package org.jboss.cache;
+
+import org.jboss.cache.lock.LockMap;
+import org.jboss.cache.util.concurrent.ConcurrentHashSet;
+
+import java.util.*;
+
+import junit.framework.TestCase;
+
+/**
+ * Class that tests LockMap performances on various access patterns and internal
implementation of readers array.
+ * Following access patterns on readers array were identified:
+ * <pre>
+ * - add to the end of the collection
+ * - remove(object); in other words random removals
+ * - contains (element)
+ * - (less frequnetly used) obtain the collection of readers and iterate over its
+ * </pre>
+ * todo - add a test to simulate concurrency (30% addition, 30%removals, 30% search and
10% iteration over the elements)
+ * @author Mircea.Markus(a)jboss.com
+ */
+public class LockMapPerformanceTest extends TestCase
+{
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ configs = new Collection[4];
+ configs[0] = new Vector<Object>();
+ configs[1] = Collections.synchronizedList(new ArrayList<Object>());
+ configs[2] = Collections.synchronizedList(new LinkedList<Object>());
+ configs[3] = new ConcurrentHashSet<Object>();
+ }
+
+ Collection<Object>[] configs;
+ int[] readersSize = {10000};
+ int repeatCount = 100;
+
+
+ public void testPlainRead()
+ {
+ for (int size : readersSize)
+ {
+ Object[] objectPool = createObjectPool(size);
+ Object[] shuffledPool = shufflePool(objectPool);
+ for (Collection<Object> col : configs)
+ {
+ LockMap lockMap = new LockMap(col);
+ String benchDescription = "[" + col.getClass().getName() + ",
" + size + "]";
+ benchmarkAddition(objectPool, lockMap, benchDescription);
+ benchmarkSearch(lockMap, shuffledPool, benchDescription);
+ benchmarkRemoval(lockMap, shuffledPool, benchDescription);
+ }
+ }
+ }
+
+ private void benchmarkRemoval(LockMap lockMap, Object[] shuffledPool, String
benchDescription)
+ {
+ long start = System.currentTimeMillis();
+ for (Object anObjectPool : shuffledPool)
+ {
+ lockMap.removeReader(anObjectPool);
+ }
+ long durration = System.currentTimeMillis() - start;
+ log("removal", durration, benchDescription);
+ }
+
+ private void benchmarkSearch(LockMap lockMap, Object[] shuffledPool, String
benchDescription)
+ {
+ long start = System.currentTimeMillis();
+ for (Object anObjectPool : shuffledPool)
+ {
+ lockMap.isOwner(anObjectPool, LockMap.OWNER_READ);
+ }
+ long durration = System.currentTimeMillis() - start;
+ log("search", durration, benchDescription);
+ }
+
+ private void benchmarkAddition(Object[] objectPool, LockMap lockMap, String
benchDescription)
+ {
+ long start = System.currentTimeMillis();
+ for (Object anObjectPool : objectPool)
+ {
+ lockMap.addReader(anObjectPool);
+ }
+ long durration = System.currentTimeMillis() - start;
+ log("addition", durration, benchDescription);
+ }
+
+ private void log(String s, long durration, String benchDescription)
+ {
+ System.out.println(benchDescription + " - " + s + " - " +
durration + " millis ");
+ }
+
+ private Object[] shufflePool(Object[] objectPool)
+ {
+ List objects = Arrays.asList(objectPool);
+ Collections.shuffle(objects);
+ return objects.toArray();
+ }
+
+ private Object[] createObjectPool(int size)
+ {
+ Object[] result = new Object[size];
+ for (int i = 0; i < size; i++)
+ {
+ result[i] = new Object();
+ }
+ return result;
+ }
+
+ int threadCount = 10;
+ int[] operationPercentage = {30, 60, 90, 100}; //additions, removals, searches,
iterations
+ int poolSize = 10;
+ int operationCount = 1000;
+ public void testConcurrnecy() throws InterruptedException
+ {
+ LockMap lm = new LockMap(Collections.synchronizedList(new LinkedList()));
+ Object[] objectPool = createObjectPool(poolSize);
+ Object mutex = new Object();
+ Accessor[] accessors = new Accessor[threadCount];
+ for (int i = 0; i < threadCount; i++)
+ {
+ accessors[i] = new Accessor(lm,objectPool,mutex);
+ accessors[i].start();
+ }
+ Thread.sleep(1000);
+ long start = System.currentTimeMillis();
+ synchronized (mutex)
+ {
+ mutex.notifyAll();
+ }
+ for (int i = 0; i < threadCount; i++)
+ {
+ try
+ {
+ accessors[i].join();
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ long durration = System.currentTimeMillis() - start;
+ System.out.println("Total durration is: " + durration);
+ }
+
+ class Accessor extends Thread
+ {
+ Random rnd = new Random();
+ LockMap lockMap;
+ Object[] objectPool;
+ Object mtex;
+
+ Accessor( LockMap lockMap, Object[] objectPool, Object mtex)
+ {
+ this.lockMap = lockMap;
+ this.objectPool = objectPool;
+ this.mtex = mtex;
+ }
+
+ int iterations;// just to avoid compiler optimizing the code
+ public void run()
+ {
+ try
+ {
+ synchronized (mtex)
+ {
+ mtex.wait();
+ }
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ System.out.println("thread started");
+ for (int i =0 ; i < operationCount; i++)
+ {
+ int operation = getOperation();
+ switch (operation) {
+ case 0: lockMap.addReader(objectPool[rnd.nextInt(poolSize)]); break;
+ case 1: lockMap.removeReader(objectPool[rnd.nextInt(poolSize)]); break;
+ case 2: lockMap.isOwner(objectPool[rnd.nextInt(poolSize)],
LockMap.OWNER_READ); break;
+ case 3:
+ {
+ for (Object obj: lockMap.readerOwners())
+ {
+ iterations ++;
+ }
+ break;
+ }
+ default:
+ {
+ throw new RuntimeException("Unknown operation :" +
operation);
+ }
+ }
+ }
+ }
+
+ private int getOperation()
+ {
+ int val = rnd.nextInt(100);
+ for (int i =0; i < operationPercentage.length; i++)
+ {
+ if (operationPercentage[i] > val)
+ {
+ return i;
+ }
+ }
+ throw new RuntimeException("Did not expect " + val);
+ }
+ }
+}
+
Show replies by date