我正在测试 BerkeleyDB Java 版以了解我是否可以在我的项目中使用它。
我创建了一个非常简单的程序,它适用于 com.sleepycat.je.Database 类的对象:
写入 N 条记录,每条 5-15kb,生成的键如 Integer.toString(random.nextInt());
读取这些记录并使用方法 Database#get 按照它们创建的顺序获取它们;
使用方法 Database#get 以随机顺序读取相同数量的记录。
我现在看到了奇怪的事情。第三次测试的执行时间随着记录数的增加呈非线性增长。
- N=80000,写入=55sec,顺序读取=17sec,随机读取=3sec
- N=100000,写入=60sec,顺序读取=20sec,随机读取=7sec
- N=120000,写入=68sec,顺序读取=27sec,随机读取=11sec
- N=140000,写入=82sec,顺序读取=32sec,随机读取=47sec
(当然,我已经多次运行测试。)
我想我做错了什么。这是参考的来源(对不起,它有点长),方法的调用顺序相同:
private Environment env;
private Database db;
private Random random = new Random();
private List<String> keys = new ArrayList<String>();
private int seed = 113;
public boolean dbOpen() {
EnvironmentConfig ec = new EnvironmentConfig();
DatabaseConfig dc = new DatabaseConfig();
ec.setAllowCreate(true);
dc.setAllowCreate(true);
env = new Environment(new File("mydbenv"), ec);
db = env.openDatabase(null, "moe", dc);
return true;
}
public int storeRecords(int i) {
int j;
long size = 0;
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry val = new DatabaseEntry();
random.setSeed(seed);
for (j = 0; j < i; j++) {
String k = Long.toString(random.nextLong());
byte[] data = new byte[5000 + random.nextInt(10000)];
keys.add(k);
size += data.length;
random.nextBytes(data);
key.setData(k.getBytes());
val.setData(data);
db.put(null, key, val);
}
System.out.println("GENERATED SIZE: " + size);
return j;
}
public int fetchRecords(int i) {
int j, res;
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry val = new DatabaseEntry();
random.setSeed(seed);
res = 0;
for (j = 0; j < i; j++) {
String k = Long.toString(random.nextLong());
byte[] data = new byte[5000 + random.nextInt(10000)];
random.nextBytes(data);
key.setData(k.getBytes());
db.get(null, key, val, null);
if (Arrays.equals(data, val.getData())) {
res++;
} else {
System.err.println("FETCH differs: " + j);
System.err.println(data.length + " " + val.getData().length);
}
}
return res;
}
public int fetchRandom(int i) {
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry val = new DatabaseEntry();
for (int j = 0; j < i; j++) {
String k = keys.get(random.nextInt(keys.size()));
key.setData(k.getBytes());
db.get(null, key, val, null);
}
return i;
}