[jbosscache-commits] JBoss Cache SVN: r5385 - core/trunk/src/test-perf/java/org/jboss/cache.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Mar 4 15:37:51 EST 2008


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 at 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);
+      }
+   }
+}
+




More information about the jbosscache-commits mailing list