关于Java读写速度的考证(3)

下边我列出以下各个大小文件,各种读取方式所花费的时间,仅作参考。
表格里边我会用Buffer作为BufferedReader的简写,Random作为RandomAccessFile的简写,FileInput作为FileInputStream的简写,Map作为内存直接映射的简写。我给出两次测试结果。

146M文件   第一次测试   第二次测试  
Buffer   4.737s   4.581s  
Random   0.251s   0.249s  
FileInput   0.27s   0.269s  
Map   0.102s   0.104s  

除了BufferedReader之外,其他的读取时间基本上没有太大区别。

356M文件   第一次测试   第二次测试  
Buffer   10.889s   10.71s  
Random   0.558s   0.589s  
FileInput   0.637s   0.635s  
Map   0.125s   0.124s  


570M文件   第一次测试   第二次测试  
Buffer   17.215s   17.393s  
Random   2.756s   2.243s  
FileInput   1.924s   1.975s  
Map   0.203s   0.197s  


712M文件   第一次测试   第二次测试  
Buffer   21.852s   23.262s  
Random   3.481s   3.529s  
FileInput   3.829s   3.42s  
Map   0.246s   0.258s  


998M文件   第一次测试   第二次测试  
Buffer   34.08s   32.437s  
Random   21.817s   20.589s  
FileInput   9.669s   9.792s  
Map   15.481s   16.886s  


由以上图表可以看出,在文件大小一般的情况下,随着文件大小的增加,内存映射基本保持在1秒以下,基本0.2s左右,而其他的都会随着文件的增大有明显的变化,这就是内存直接映射秒杀的地方,但是就是文件增加到了998M之后,时间突然之间会增加很大,不知道是不是因为文件太大,以致于内存里边需要执行操作系统提供的一些保护算法而浪费时间了,这个有待考证,也可能是每次运行完之后没有清理内存,导致数据堵塞,因为内存映射方式,Java没有提供相应的直接回收MappedByteBuffer区域的方法,这也会导致另外一种异常就是内存不够。

然后我在网上搜了两种解决方式,但是我自己也没有实验出来,代码是执行了,但是不知道从哪里看出他执行前后的区别。这里也把代码放上。

第一种方式:

System.gc();
System.runFinalization();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();

第二种方式:

public static void unmap(final MappedByteBuffer buffer) {
if (buffer == null) {
return;
}
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);
if (getCleanerMethod != null) {
getCleanerMethod.setAccessible(true);
Object cleaner = getCleanerMethod.invoke(buffer, new Object[0]);
Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);
if (cleanMethod != null) {
cleanMethod.invoke(cleaner, new Object[0]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});

但是执行这个之后,会把时间拖慢,也是一个问题,所以这个问题待解决。

上边是我测试了几个方式的读取方式,这样以后实验室的使用读取文件的方式的时候,可以选用最适合的方式,如果时间是最紧要的,那么可以选用内存直接映射,但是这个要保证内存够用,而且文件合适的情况下,至于上边的那个问题,下边我会继续关注,如果谁了解了,欢迎提示~

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/1fea3e70d013ca51f5ed5c49405a7145.html