次のコードをベンチマークとして使用すると、システムはわずか 1 秒で 10,000 行をディスクに書き込むことができます。
void withSync() {
int f = open( "/tmp/t8" , O_RDWR | O_CREAT );
lseek (f, 0, SEEK_SET );
int records = 10*1000;
clock_t ustart = clock();
for(int i = 0; i < records; i++) {
write(f, "012345678901234567890123456789" , 30);
fsync(f);
}
clock_t uend = clock();
close (f);
printf(" sync() seconds:%lf writes per second:%lf\n", ((double)(uend-ustart))/(CLOCKS_PER_SEC), ((double)records)/((double)(uend-ustart))/(CLOCKS_PER_SEC));
}
上記のコードでは、10,000 レコードを書き込み、ディスクにフラッシュするのを一瞬で行うことができます。出力は以下のとおりです。
sync() seconds:0.006268 writes per second:0.000002
Java 版では、10,000 レコードを書き込むのに 4 秒以上かかります。これは Java の単なる制限ですか、それとも何か不足していますか?
public void testFileChannel() throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("/tmp/t5"),"rw");
FileChannel c = raf.getChannel();
c.force(true);
ByteBuffer b = ByteBuffer.allocateDirect(64*1024);
long s = System.currentTimeMillis();
for(int i=0;i<10000;i++){
b.clear();
b.put("012345678901234567890123456789".getBytes());
b.flip();
c.write(b);
c.force(false);
}
long e=System.currentTimeMillis();
raf.close();
System.out.println("With flush "+(e-s));
}
これを返します:
With flush 4263
Javaでレコードをディスクに書き込む正しい/最速の方法を理解するのを手伝ってください。
注:最終的には、このファイルに対するランダムな読み取り/書き込みアクセスが必要になるため、このRandomAccessFile
クラスを a と組み合わせて使用しています。ByteBuffer