【发布时间】:2012-10-29 10:50:41
【问题描述】:
使用以下代码作为基准,系统可以在几分之一秒内将 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 类与ByteBuffer 结合使用,因为最终我们需要对该文件进行随机读/写访问。
【问题讨论】:
-
您的比较不公平。您正在使用 ByteBuffer 并在 Java 版本中调用 .getBytes() 。如果您的想法是测试应用程序的性能,那么这没关系。但是与 C 相比,这是不公平的,因为您在做不同的事情。
-
这很公平。使用 ByteBuffer 和 .getBytes 实际上比在 Java 中以任何其他方式执行它更快(至少在我的机器上的测试中)。如果您对如何在 Java 中进行随机访问有其他建议,我很乐意听取他们的意见。谢谢!
标签: java c performance disk