Jisp,A small, embedded database engine written in Pure Java.Jisp Performance is slower than Perst,db4o,jdbm,Berkeley DB Java Database.
The TestIndex benchmark measures the performance of such basic operations as storing/fetching objects and locating objects using an index. This test contains three steps:
Time to execute each step is measured in milliseconds. The number of records in each case is the same - 100,000. All tests were executed on the same computer: AMD Athlon 64 *2 (4000+), 2.0Gb RAM, WinXP, and Sun Java JDK version 1.5.0_07.
Result:
Elapsed time for inserting 100000 records: 69857 milliseconds
Elapsed time for performing 200000 index searches: 10656 milliseconds
Elapsed time for iterating through 200000 records: 8546 milliseconds
Elapsed time for deleting 100000 records: 80638 milliseconds
Jisp Version:
jisp-2.5.1.jar
Code:
import java.io.Serializable;
import com.coyotegulch.jisp.BTreeIndex;
import com.coyotegulch.jisp.BTreeIterator;
import com.coyotegulch.jisp.IndexedObjectDatabase;
import com.coyotegulch.jisp.KeyObject;
import com.coyotegulch.jisp.LongKey;
import com.coyotegulch.jisp.StringKey;
public class TestIndex {
final static int nRecords = 100000;
final static int btreeOrder = 33;static class Record implements Serializable {
public long intKey;
public String strKey;
}static public void main(String[] args) throws Exception {
IndexedObjectDatabase database = new IndexedObjectDatabase("testindex", true);
BTreeIndex intIndex = new BTreeIndex("intindex",btreeOrder,new JispKey(),false);
BTreeIndex strIndex = new BTreeIndex("strindex",btreeOrder,new JispKey(),false);
database.attachIndex(intIndex);
database.attachIndex(strIndex);
long start = System.currentTimeMillis();
long key = 1999;
int i;
for (i = 0; i < nRecords; i++) {
Record rec = new Record();
key = (3141592621L*key + 2718281829L) % 1000000007L;
rec.intKey = key;
rec.strKey = Long.toString(key);
KeyObject [] keyArray = new KeyObject[2];
keyArray[0] = new LongKey(rec.intKey);
keyArray[1] = new StringKey(rec.strKey);
database.write(keyArray, rec);
}
System.out.println("Elapsed time for inserting " + nRecords + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");start = System.currentTimeMillis();
key = 1999;
for (i = 0; i < nRecords; i++) {
key = (3141592621L*key + 2718281829L) % 1000000007L;
String strKey = Long.toString(key);Record result = (Record)database.read(new LongKey(key), intIndex);
if (result.intKey != key || !strKey.equals(result.strKey)) {
throw new Error("Long key search failed");
}
result = (Record)database.read(new StringKey(Long.toString(key)), strIndex);if (result.intKey != key || !strKey.equals(result.strKey)) {
throw new Error("String key search failed");
}
}
System.out.println("Elapsed time for performing " + nRecords*2 + " index searches: "
+ (System.currentTimeMillis() - start) + " milliseconds");
start = System.currentTimeMillis();
BTreeIterator iterator = new BTreeIterator(intIndex);
key = Long.MIN_VALUE;
i = 0;
do {Record result = (Record)database.read(iterator);
if (result.intKey < key) {
throw new Error("Invalid long key order");
}
key = result.intKey;
i++;
} while (iterator.moveNext());
if (i != nRecords) {
throw new Error("Incorrect number of records: " + i);
}
String strKey = "";
iterator = new BTreeIterator(strIndex);
i = 0;
do {
Record result = (Record)database.read(iterator);
if (result.strKey.compareTo(strKey) < 0) {
throw new Error("Invalid long key order");
}
strKey = result.strKey;
i++;
} while (iterator.moveNext());if (i != nRecords) {
throw new Error("Incorrect number of records: " + i);
}
System.out.println("Elapsed time for iterating through " + (nRecords*2) + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");
start = System.currentTimeMillis();
key = 1999;
for (i = 0; i < nRecords; i++) {
key = (3141592621L*key + 2718281829L) % 1000000007L;
KeyObject[] kos=new KeyObject[2];
kos[0]=new LongKey(key);
kos[1]=new StringKey(Long.toString(key));
database.remove(kos);
}
System.out.println("Elapsed time for deleting " + nRecords + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");
}
}
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;import com.coyotegulch.jisp.KeyObject;
/**
* Wrapper class for Keys to be compatible with the
* Jisp KeyObject.
*
* @author Avalon Development Team
* @version CVS $Id: JispKey.java,v 1.4 2004/02/28 11:47:31 cziegeler Exp $
*/
public final class JispKey extends KeyObject
{
final static long serialVersionUID = -1216913992804571313L;protected Object m_Key;
static protected JispKey NULL_KEY = new JispKey("");
public JispKey() {
this("");
}
/**
* Constructor for the JispKey object
*
* @param keyValue the key
*/
public JispKey(Object keyValue)
{
m_Key = keyValue;
}/**
* Compares two Keys
*
* @param key the KeyObject to be compared
* @return 0 if equal, 1 if greater, -1 if less
*/public int compareTo(KeyObject key)
{
if (key instanceof JispKey)
{
final JispKey other = (JispKey)key;
if ( other.m_Key.hashCode() == m_Key.hashCode() )
{
if ( m_Key == other.m_Key || m_Key.equals(other.m_Key) )
{
return KEY_EQUAL;
}
// we have the same hashcode, but different keys
// this is usually an error condition, but we deal
// with it anway
// if they would have the same classname, they
// can only have the same hashCode if they are equal:
int comp = m_Key.getClass().getName().compareTo(other.m_Key.getClass().getName());
if ( comp < 0 )
{
return KEY_LESS;
}
return KEY_MORE;
}
else
{
if ( m_Key.hashCode() < other.m_Key.hashCode() )
{
return KEY_LESS;
}
return KEY_MORE;
}
}
else
{
return KEY_ERROR;
}
}/**
* Composes a null Kewy
*
* @return a null Key
*/
public KeyObject makeNullKey()
{
return NULL_KEY;
}/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings,
* and arrays.
*
* @param out the stream to write the object to
* @exception IOException
*/
public void writeExternal(ObjectOutput out)
throws IOException
{
out.writeObject(m_Key);
}/**
* The object implements the readExternal method to restore its contents
* by calling the methods of DataInput for primitive types and readObject
* for objects, strings and arrays. The readExternal method must read the
* values in the same sequence and with the same types as were written by writeExternal.
*
* @param in the stream to read data from in order to restore the object
* @exception IOException
* @exception ClassNotFoundException
*/
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
{
m_Key = in.readObject();
}/**
* Return the real key
*/
public Object getKey()
{
return m_Key;
}
}