BerkeleyDB Java Editionをテストして、プロジェクトで使用できるかどうかを理解しています。
クラスcom.sleepycat.je.Databaseのオブジェクトで動作する非常に単純なプログラムを作成しました。
Integer.toString(random.nextInt());のように生成されたキーを使用して、それぞれ5〜15kbのNレコードを書き込みます。
これらのレコードを読み取り、作成されたのと同じ順序でメソッドDatabase#getを使用してそれらをフェッチします。
メソッドDatabase#getを使用して同じ数のレコードをランダムな順序で読み取ります。
そして今、私は奇妙なことを見ています。3番目のテストの実行時間は、レコード数の増加に伴って非常に非線形に増加します。
- N = 80000、書き込み= 55秒、シーケンシャルフェッチ= 17秒、ランダムフェッチ=3秒
- N = 100000、書き込み= 60秒、シーケンシャルフェッチ= 20秒、ランダムフェッチ=7秒
- N = 120000、書き込み= 68秒、シーケンシャルフェッチ= 27秒、ランダムフェッチ=11秒
- N = 140000、書き込み= 82秒、順次フェッチ= 32秒、ランダムフェッチ=47秒
(もちろん、テストを数回実行しました。)
私はかなり間違ったことをしていると思います。参照用のソースは次のとおりです(申し訳ありませんが、少し長いです)。メソッドは同じ順序で呼び出されます。
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;
}