Berkeley DB Java版性能测试评估
Berkeley DB 性能测试评估,最近想选择一个轻量、可伸缩、高性能的嵌入式数据库,所以对Berkeley DB Java版数据库进行了测试评估。从结果看来Berkeley DB Java版还是值得试一试。
版本:
je-3.3.75.zip
结果:
Elapsed time for inserting 100000 records: 12672 milliseconds
Elapsed time for performing 200000 index searches: 10844 milliseconds
Elapsed time for iterating through 200000 records: 5297 milliseconds
Elapsed time for deleting 100000 records: 15859 milliseconds
Elapsed time for database close 1593 milliseconds
测试代码:
import java.io.File;
import java.io.Serializable;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.*;
import com.sleepycat.bind.tuple.*;
import com.sleepycat.je.*;class TestBerkeleyIndex {
final static int nRecords = 100000;public static void main(String argv[]) throws DatabaseException {
Cursor cursor;
OperationStatus status;
File envHomeDirectory = new File("dbenv");
if(!envHomeDirectory.exists()){
envHomeDirectory.mkdir();
}EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
Environment exampleEnv = new Environment(envHomeDirectory, envConfig);
Transaction txn = exampleEnv.beginTransaction(null, null);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
Database exampleDb = exampleEnv.openDatabase(txn, "bindingsDb", dbConfig);DatabaseConfig catalogConfig = new DatabaseConfig();
catalogConfig.setTransactional(true);
catalogConfig.setAllowCreate(true);
Database catalogDb = exampleEnv.openDatabase(txn,
"catalogDb",
catalogConfig);
StoredClassCatalog catalog = new StoredClassCatalog(catalogDb);
EntryBinding keyBinding =
TupleBinding.getPrimitiveBinding(Long.class);EntryBinding dataBinding = new SerialBinding(catalog, Record.class);
EntryBinding secKeyBinding = TupleBinding.getPrimitiveBinding(String.class);SecondaryConfig secConfig = new SecondaryConfig();
secConfig.setTransactional(true);
secConfig.setAllowCreate(true);
secConfig.setSortedDuplicates(true);
secConfig.setKeyCreator(new MyKeyCreator(secKeyBinding, dataBinding));
SecondaryDatabase exampleSecDb = exampleEnv.openSecondaryDatabase(txn,
"bindingsSecDb",
exampleDb,
secConfig);
txn.commit();DatabaseEntry keyEntry = new DatabaseEntry();
DatabaseEntry dataEntry = new DatabaseEntry();
long start = System.currentTimeMillis();
long key = 1999;
int i;
txn = exampleEnv.beginTransaction(null, null);
for (i = 0; i < nRecords; i++) {
Record rec = new Record();
key = (3141592621L*key + 2718281829L) % 1000000007L;
rec.intKey = key;
rec.strKey = Long.toString(key);LongBinding.longToEntry(key, keyEntry);
dataBinding.objectToEntry(rec, dataEntry);status = exampleDb.put(txn, keyEntry, dataEntry);
if (status != OperationStatus.SUCCESS) {
throw new DatabaseException("Data insertion got status " + status);
}
}
txn.commit();
System.out.println("Elapsed time for inserting " + nRecords + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");start = System.currentTimeMillis();
key = 1999;
txn = exampleEnv.beginTransaction(null, null);
for (i = 0; i < nRecords; i++) {
key = (3141592621L*key + 2718281829L) % 1000000007L;
String strKey = Long.toString(key);
StringBinding.stringToEntry(strKey, keyEntry);
status = exampleSecDb.get(txn, keyEntry, dataEntry, LockMode.DEFAULT);
if (status != OperationStatus.SUCCESS) {
throw new DatabaseException("String key search failed with status " + status);
}
Record r1 = (Record)dataBinding.entryToObject(dataEntry);
if (r1.intKey != key || !r1.strKey.equals(strKey)) {
throw new DatabaseException("Wrong string key");
}LongBinding.longToEntry(key, keyEntry);
status = exampleDb.get(txn, keyEntry, dataEntry, LockMode.DEFAULT);
if (status != OperationStatus.SUCCESS) {
throw new DatabaseException("Long key search failed with status " + status);
}
Record r2 = (Record)dataBinding.entryToObject(dataEntry);
if (r2.intKey != key || !r2.strKey.equals(strKey)) {
throw new DatabaseException("Wrong long key");
}
}
txn.commit();
System.out.println("Elapsed time for performing " + nRecords*2 + " index searches: "
+ (System.currentTimeMillis() - start) + " milliseconds");
start = System.currentTimeMillis();
txn = exampleEnv.beginTransaction(null, null);
cursor = exampleDb.openCursor(null, null);
key = Long.MIN_VALUE;
for (i = 0; cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) == OperationStatus.SUCCESS; i++) {
Record rec = (Record)dataBinding.entryToObject(dataEntry);
if (rec.intKey < key) {
throw new DatabaseException("Wrong long key order");
}
key = rec.intKey;
}
cursor.close();cursor = exampleSecDb.openCursor(null, null);
String strKey = "";
for (i = 0; cursor.getNext(keyEntry, dataEntry, LockMode.DEFAULT) == OperationStatus.SUCCESS; i++) {
Record rec = (Record)dataBinding.entryToObject(dataEntry);
if (rec.strKey.compareTo(strKey) < 0) {
throw new DatabaseException("Wrong string key order");
}
strKey = rec.strKey;
}
cursor.close();
txn.commit();
System.out.println("Elapsed time for iterating through " + (nRecords*2) + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");
start = System.currentTimeMillis();
txn = exampleEnv.beginTransaction(null, null);
key = 1999;
for (i = 0; i < nRecords; i++) {
key = (3141592621L*key + 2718281829L) % 1000000007L;
LongBinding.longToEntry(key, keyEntry);
status = exampleDb.delete(txn, keyEntry);
if (status != OperationStatus.SUCCESS) {
throw new DatabaseException("Long key search failed with status " + status);
}
}
txn.commit();
System.out.println("Elapsed time for deleting " + nRecords + " records: "
+ (System.currentTimeMillis() - start) + " milliseconds");
start = System.currentTimeMillis();
catalogDb.close();
exampleSecDb.close();
exampleDb.close();
exampleEnv.close();
System.out.println("Elapsed time for database close "
+ (System.currentTimeMillis() - start) + " milliseconds");
}private static class Record implements Serializable {
public long intKey;
public String strKey;
}private static class MyKeyCreator implements SecondaryKeyCreator {
private EntryBinding secKeyBinding;
private EntryBinding dataBinding;MyKeyCreator(EntryBinding secKeyBinding, EntryBinding dataBinding) {
this.secKeyBinding = secKeyBinding;
this.dataBinding = dataBinding;
}public boolean createSecondaryKey(SecondaryDatabase secondaryDb,
DatabaseEntry keyEntry,
DatabaseEntry dataEntry,
DatabaseEntry resultEntry)
throws DatabaseException
{Record rec = (Record) dataBinding.entryToObject(dataEntry);
secKeyBinding.objectToEntry(rec.strKey, resultEntry);
return true;
}
}
}