[jboss-cvs] JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader ...
Mircea Markus
mircea.markus at gmail.com
Sat Feb 10 12:47:02 EST 2007
User: mmarkus
Date: 07/02/10 12:47:02
Added: tests/perf/org/jboss/cache/manualtests/cacheloader
Benchmark.java BenchmarkRunner.java
BaseBenchmark.java RepeatingBenchmark.java
OneConnectionFactory.java
Log:
JDBCCaheLoader performance improvements. Also added benchmarks for comparisons and backward compatibility tests
Revision Changes Path
1.1 date: 2007/02/10 17:47:02; author: mmarkus; state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/Benchmark.java
Index: Benchmark.java
===================================================================
package org.jboss.cache.manualtests.cacheloader;
import org.jboss.cache.loader.*;
import org.jboss.cache.Fqn;
import org.jboss.cache.CacheImpl;
import org.jboss.cache.DefaultCacheFactory;
import java.util.*;
/**
* Defines the algorithm used for measuring performance. The actual operation that will be investigated is defined
* in a subclass. Buidls a homogeneous tree structure of configurable depth, each node having the same number
* of chlidren and the same associated attribute map. The persisted tree represents the fixture for the benchmak-ed
* operation.
*
* Benchmarks are runed through {@link BenchmarkRunner}
*
* @author Mircea.Markus at iquestint.com
* @version 1.0
*/
public abstract class Benchmark
{
/**
* When recursively building the tree, stop at this depth.
*/
protected abstract int getDepth();
/**
* When recursively building the tree, for each node <tt>numberOfChildren</tt> children
*/
protected abstract int getNumnerOfChildren();
/**
* The actual loader implementation. Not started.
*/
protected abstract CacheLoader getCacheLoader() throws Exception;
/**
* This method will be called with all the nodes that are about to be added. Implementations can filter them
* or scuffle etc.
*/
protected abstract List<Fqn> beforeInsertion(List<Fqn> nodesToAdd);
/**
* When recursively building the tree, for each node persist this attribute map.
*/
protected abstract Map getAttributeMap(Fqn fqn);
/**
* The analysed operation will only be performed on those node. E.g. in the case of remove, select a list of nodes
* of various depths for which you want to compare the perfomance.
*/
protected abstract List<Fqn> selectRelevantNodes(List<Fqn> allNodes);
/**
* Perform the call(set of calls) for which you want to measure performance. Clock will be started right before
* calling this.
*/
protected abstract void processOperation(Fqn node, CacheLoader loader) throws Exception;
/**
* Register operation duration. Calld imediatelly after <tt>processOperation</tt>.
*/
protected abstract void logOperationDuration(long duration, Fqn processedFqn);
/**
* Logs the duration of persisisting the test tree structure. Does not include the time needed for
* generating the test tree structure.
*/
protected abstract void logInsertionDuration(long duration);
/**
* Return the name of the benchmark.
*/
protected abstract String getName();
public void testPerformance() throws Exception
{
int numnerOfChildren = getNumnerOfChildren();
int depth = getDepth();
List<Fqn> nodesToAdd = buildTree(depth, numnerOfChildren);
CacheLoader cacheLoader = getCacheLoader();
cacheLoader.setCache((CacheImpl) DefaultCacheFactory.getInstance().createCache(false));//this is needed for marshaller
cacheLoader.start();
cacheLoader.remove(Fqn.ROOT);
//1st step = preprocess nodes to add
List<Fqn> processedNodes = beforeInsertion(nodesToAdd);
//2nd step = add all the nodes
long insStartTime = System.currentTimeMillis();
for (Fqn fqn : processedNodes)
{
cacheLoader.put(fqn, getAttributeMap(fqn));
}
logInsertionDuration(System.currentTimeMillis() - insStartTime);
//3d step = select relevant nodes for our operation
List<Fqn> relevantNodes = selectRelevantNodes(processedNodes);
//4th step - perform the desired operation on each selected node and log performance
for (Fqn node : relevantNodes)
{
long startTime = System.currentTimeMillis();
processOperation(node, cacheLoader);
logOperationDuration(System.currentTimeMillis() - startTime, node);
}
cacheLoader.stop();
}
protected List<Fqn> buildTree(int depth, int numberOfChildren) throws Exception
{
List<Fqn> treeNodes = new ArrayList<Fqn>();
for (int i = 0; i < numberOfChildren; i++)
{
buildNode(i, 1, "", depth, numberOfChildren, treeNodes);
}
return treeNodes;
}
private void buildNode(int sequence, int depth, String parent, int maxDepth, int numberOfChildren,
List<Fqn> treeNodes)
{
String newFqn = parent + Fqn.SEPARATOR + depth + "_" + sequence;
Fqn thisNode = Fqn.fromString(newFqn);
treeNodes.add(thisNode);
if (depth < maxDepth)
{
for (int i = 0; i < numberOfChildren; i++)
{
buildNode(i, depth + 1, thisNode.toString(), maxDepth, numberOfChildren, treeNodes);
}
}
}
}
1.1 date: 2007/02/10 17:47:02; author: mmarkus; state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/BenchmarkRunner.java
Index: BenchmarkRunner.java
===================================================================
package org.jboss.cache.manualtests.cacheloader;
import org.jboss.cache.manualtests.cacheloader.newimpl.*;
import org.jboss.cache.manualtests.cacheloader.oldimpl.*;
/**
* Entry point for running the benchmarks. The benchmark to be run are defined here, see "benchmark" static field.
*
* @author Mircea.Markus at iquestint.com
* @version 1.0
*/
public class BenchmarkRunner
{
private static String[] benchmarks = {
RemoveNewBenchmark.class.getName(),
LoadNewBenchmark.class.getName(),
ChildrenNamesNewBenchmark.class.getName(),
GetAttributesNewBenchmark.class.getName(),
ExistsNewBenchmark.class.getName(),
/* end of new impl benchmarks */
RemoveOldBenchmark.class.getName(),
LoadOldBenchmark.class.getName(),
ChildrenNamesOldBenchmark.class.getName(),
GetAttributesOldBenchmark.class.getName(),
ExistsOldBenchmark.class.getName()
};
public static void main(String[] args) throws Exception
{
for (int i = 0; i < benchmarks.length; i++)
{
Benchmark benchmark = (Benchmark) Class.forName(benchmarks[i]).newInstance();
System.out.println("Running benchmark " + benchmark.getName());
benchmark.testPerformance();
System.out.println("Done running benchmark " + benchmark.getName() + "\n \n");
}
}
}
1.1 date: 2007/02/10 17:47:02; author: mmarkus; state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/BaseBenchmark.java
Index: BaseBenchmark.java
===================================================================
package org.jboss.cache.manualtests.cacheloader;
import org.jboss.cache.Fqn;
import org.jboss.cache.factories.XmlConfigurationParser;
import org.jboss.cache.xml.XmlHelper;
import org.jboss.cache.config.CacheLoaderConfig;
import org.w3c.dom.Element;
import java.util.*;
/**
* Implements the common operations.
* @see Benchmark
*
* @author Mircea.Markus at iquestint.com
* @version 1.0
*/
public abstract class BaseBenchmark extends Benchmark
{
public static final int NUMBER_OF_CHILDREN = 3;
public static final int DEPTH = 7;
public static final Map ATTRIBUTE_MAP = new HashMap();
static
{
ATTRIBUTE_MAP.put("a", "b");
ATTRIBUTE_MAP.put("b", "c");
ATTRIBUTE_MAP.put("c", "d");
ATTRIBUTE_MAP.put("d", "e");
}
protected int getDepth()
{
return DEPTH;
}
protected int getNumnerOfChildren()
{
return NUMBER_OF_CHILDREN;
}
protected List<Fqn> beforeInsertion(List<Fqn> nodesToAdd)
{
Collections.shuffle(nodesToAdd);
return nodesToAdd;
}
protected Map getAttributeMap(Fqn fqn)
{
return ATTRIBUTE_MAP;
}
protected List<Fqn> selectRelevantNodes(List<Fqn> allNodes)
{
List<Fqn> result = new ArrayList<Fqn>();
selectAtThisDepth(Fqn.ROOT, 1, result);
Collections.reverse(result);
return result;
}
private static void selectAtThisDepth(Fqn parent, int depth, List<Fqn> result)
{
String forRemoval = parent + Fqn.SEPARATOR + depth + "_" + 0;
Fqn forRemovalFqn = Fqn.fromString(forRemoval);
result.add(forRemovalFqn);
if (depth < DEPTH)
{
String next = parent + Fqn.SEPARATOR + depth + "_" + 1;
Fqn nextFqn = Fqn.fromString(next);
selectAtThisDepth(nextFqn, depth + 1, result);
}
}
protected void logOperationDuration(long duration, Fqn processedFqn)
{
System.out.println((getDepth() + 1) - processedFqn.size() + " " + duration);
}
protected void logInsertionDuration(long duration)
{
System.out.println("Insertion took = " + duration);
}
protected CacheLoaderConfig getSingleCacheLoaderConfig(boolean passivation, String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState, boolean shared, boolean purgeOnStartup) throws Exception
{
String xml = "<config>\n" +
"<passivation>" + passivation + "</passivation>\n" +
"<preload>" + preload + "</preload>\n" +
"<cacheloader>\n" +
"<class>" + cacheloaderClass + "</class>\n" +
"<properties>" + properties + "</properties>\n" +
"<async>" + async + "</async>\n" +
"<shared>" + shared + "</shared>\n" +
"<fetchPersistentState>" + fetchPersistentState + "</fetchPersistentState>\n" +
"<purgeOnStartup>" + purgeOnStartup + "</purgeOnStartup>\n" +
"</cacheloader>\n" +
"</config>";
Element element = XmlHelper.stringToElement(xml);
return XmlConfigurationParser.parseCacheLoaderConfig(element);
}
protected Properties getProperties() throws Exception
{
Properties prop = new Properties();
try
{
prop.load(this.getClass().getClassLoader().getResourceAsStream("cache-jdbc.properties"));
return prop;
}
catch (Exception e)
{
throw new Exception("Error loading jdbc properties ", e);
}
}
}
1.1 date: 2007/02/10 17:47:02; author: mmarkus; state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/RepeatingBenchmark.java
Index: RepeatingBenchmark.java
===================================================================
package org.jboss.cache.manualtests.cacheloader;
import org.jboss.cache.Fqn;
import org.jboss.cache.loader.CacheLoader;
/**
* Executing some operations only once is not relevant. E.g. in the case of exits() we only get relevant timing when
* executing it 10 timese or so.
*
* @author Mircea.Markus at iquestint.com
* @version 1.0
*/
public abstract class RepeatingBenchmark extends BaseBenchmark
{
public static final int NUMBER_OF_TIMES = 100;
protected void processOperation(Fqn node, CacheLoader loader) throws Exception
{
for (int i = 0; i < NUMBER_OF_TIMES; i++)
{
repeatOperation(node, loader);
}
}
public abstract void repeatOperation(Fqn node, CacheLoader loader) throws Exception;
}
1.1 date: 2007/02/10 17:47:02; author: mmarkus; state: Exp;JBossCache/tests/perf/org/jboss/cache/manualtests/cacheloader/OneConnectionFactory.java
Index: OneConnectionFactory.java
===================================================================
package org.jboss.cache.manualtests.cacheloader;
import org.jboss.cache.loader.ConnectionFactory;
import org.jboss.cache.loader.AdjListJDBCClassLoaderConfig;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
/**
* Gives only one connection all the time. There is no need for pooling as all the operations are performed
* sequentially - so this is the leess time consuming poolig mechanism available.
*
* @author Mircea.Markus at iquestint.com
* @version 1.0
*/
public class OneConnectionFactory implements ConnectionFactory
{
private AdjListJDBCClassLoaderConfig config;
private Connection conn;
public void setConfig(AdjListJDBCClassLoaderConfig config)
{
this.config = config;
}
public void start() throws Exception
{
Class.forName(config.getDriverClass());
conn = DriverManager.getConnection(config.getJdbcURL(), config.getJdbcUser(), config.getJdbcPassword());
}
public Connection getConnection() throws SQLException
{
return conn;
}
public void prepare(Object tx)
{
}
public void commit(Object tx)
{
}
public void rollback(Object tx)
{
}
public void close(Connection con)
{
}
public void stop()
{
try
{
conn.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
More information about the jboss-cvs-commits
mailing list