【发布时间】:2015-02-10 00:32:15
【问题描述】:
我的印象是使用 FileChannel 和 ByteBuffer 会加快读取时间,但它似乎比从文件流中读取要慢得多。我在这里做错了吗?
FileInputStream fis = new FileInputStream("C:\\Users\\blah\\Desktop\\del\\pg28054.txt");
FileOutputStream fos = new FileOutputStream("C:\\Users\\blah\\Desktop\\del\\readme.txt");
FileChannel fcin = fis.getChannel();
FileChannel fcout = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
long startTime = System.currentTimeMillis();
long endtime = System.currentTimeMillis();
while(true){
buffer.clear();
int r = fcin.read(buffer);
if(r==-1){
break;
}
buffer.flip();
fcout.write(buffer);
}
endtime = System.currentTimeMillis();
System.out.println("time to read and write(ms) " + (endtime - startTime));
以上在 108 毫秒内完成,而以下实现在 43 毫秒内完成
long startTime;
long endtime;
FileInputStream fis1 = new FileInputStream("C:\\Users\\blah\\Desktop\\del\\pg28054.txt");
FileOutputStream fos1 = new FileOutputStream("C:\\Users\\blah\\Desktop\\del\\readme1.txt");
byte b[] = null;
startTime = System.currentTimeMillis();
while(true){
b = new byte[1024];
int r = fis1.read(b);
if(r==-1){
break;
}
fos1.write(b);
}
endtime = System.currentTimeMillis();
System.out.println("time to read and write(ms) " + (endtime - startTime));
【问题讨论】:
-
微基准测试的常见问题是:您是否在 JVM 中多次运行实验,让 JIT 有足够的时间完成其工作?您是否使用
--XX:+PrintCompilation来确认 JIT 对于您使用其值的运行是安静的?一个直接的想法是,第一个代码块可能会引入更多的类(这需要更大的开销),即使这些类在经过 JIT 等处理后会产生更快的代码。 -
多一点信息会更好 - 你的文件有多大。你是如何运行你的基准测试的。
-
您究竟从哪里得到的印象是这个案子应该更快?注意你的复制循环都是无效的。 NIO 循环应该调用
compact()而不是clear(),,java.io循环应该调用fos1.write(b, 0, r)。否则会有数据丢失的风险。 -
在您的第二次测试中,您不一定写出正确的数据。你应该打电话给
fos1.write(b,0,r),而不是fos1.write(b)。