前言
众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例:
面向字节流的:FileOutputStream 和 BufferedOutputStream
面向字符流的:FileWriter 和 BufferedWriter
近年来发展出New I/O ,也叫NIO,里面又包装了两个类:NewOutputStream 和 NewBufferedWriter
现在,我们建立测试程序,比较这些类写入文件的性能。
机器配置
" cdata_tag="style">
Processor Name: Intel Core i7
Processor Speed: 2.2 GHz
Number of Processors: 1
Total Number of Cores: 4
L2 Cache (per Core): 256 KB
L3 Cache: 6 MB
Memory: 16 GB
测试程序
纵向比较:几种文件操作类向文件中写入相同行数的内容(每行内容均为“写入文件Data\n”),比较其耗费时间
横向比较:对于同一个文件操作类,比较写入不同行数内容情况下所耗费时间;本文以2的次方指数级增长行数
1 import java.io.File; 2 import java.io.FileOutputStream; 3 import java.io.*; 4 import java.nio.file.Files; 5 import java.nio.file.Paths; 6 7 public class testFileIO { 8 9 public static void testDriver () throws IOException { 10 int maxlineNum = 100000001;//写入文件的最大行数 11 int startlineNum = 1;//写入文件的行数 12 int Multiplying = 2;//行数增长倍率 13 14 long begin = 0L; 15 long end = 0L; 16 17 //将时间统计写入文件Result.txt中 18 FileWriter fileWriter = new FileWriter("./Result.txt", true); 19 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); 20 21 System.out.println("Test FileOutputStream begin."); 22 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 23 begin = System.currentTimeMillis(); 24 testFileOutputStream(lineNum); 25 end = System.currentTimeMillis(); 26 long timeElapse_FileOutputStream = end - begin; 27 bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t"); 28 } 29 System.out.println("Test FileOutputStream end.\n"); 30 31 System.out.println("Test BufferedOutputStream begin."); 32 bufferedWriter.write("\n"); 33 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 34 begin = System.currentTimeMillis(); 35 testBufferedOutputStream(lineNum); 36 end = System.currentTimeMillis(); 37 long timeElapse_BufferedOutputStream = end - begin; 38 bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t"); 39 } 40 System.out.println("Test BufferedOutputStream end.\n"); 41 42 System.out.println("Test FileWriter begin."); 43 bufferedWriter.write("\n"); 44 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 45 begin = System.currentTimeMillis(); 46 testFileWriter(lineNum); 47 end = System.currentTimeMillis(); 48 long timeElapse_FileWriter = end - begin; 49 bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t"); 50 } 51 System.out.println("Test FileWriter end.\n"); 52 53 System.out.println("Test BufferedWriter begin."); 54 bufferedWriter.write("\n"); 55 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 56 begin = System.currentTimeMillis(); 57 testBufferedWriter(lineNum); 58 end = System.currentTimeMillis(); 59 long timeElapse_BufferedWriter = end - begin; 60 bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t"); 61 } 62 System.out.println("Test BufferedWriter end.\n"); 63 64 System.out.println("Test NewOutputStream begin."); 65 bufferedWriter.write("\n"); 66 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 67 begin = System.currentTimeMillis(); 68 testNewOutputStream(lineNum); 69 end = System.currentTimeMillis(); 70 long timeElapse_NewOutputStream = end - begin; 71 bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t"); 72 } 73 System.out.println("Test NewOutputStream end.\n"); 74 75 System.out.println("Test NewBufferedWriter begin."); 76 bufferedWriter.write("\n"); 77 for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) { 78 begin = System.currentTimeMillis(); 79 testNewBufferedWriter(lineNum); 80 end = System.currentTimeMillis(); 81 long timeElapse_NewBufferedWriter = end - begin; 82 bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t"); 83 } 84 System.out.println("Test NewOutputStream end.\n"); 85 86 bufferedWriter.close(); 87 } 88 89 /************************** I/O *****************************/ 90 //面向字节 91 public static void testFileOutputStream (int lineNum) throws IOException { 92 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt")); 93 while (--lineNum > 0) { 94 fileOutputStream.write("写入文件Data\n".getBytes()); 95 } 96 fileOutputStream.close(); 97 } 98 99 public static void testBufferedOutputStream (int lineNum) throws IOException {100 FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));101 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);102 while (--lineNum > 0) {103 bufferedOutputStream.write("写入文件Data\n".getBytes());104 }105 bufferedOutputStream.close();106 }107 108 //面向字符109 public static void testFileWriter (int lineNum) throws IOException {110 FileWriter fileWriter = new FileWriter("./testFileWriter.txt");111 while (--lineNum > 0) {112 fileWriter.write("写入文件Data\n");113 }114 fileWriter.close();115 }116 117 public static void testBufferedWriter (int lineNum) throws IOException {118 FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");119 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);120 while (--lineNum > 0) {121 bufferedWriter.write("写入文件Data\n");122 }123 bufferedWriter.close();124 }125 126 127 /************************** NIO ****************************/128 public static void testNewOutputStream (int lineNum) throws IOException {129 OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));130 while (--lineNum > 0) {131 outputStream.write("写入文件Data\n".getBytes());132 }133 outputStream.close();134 }135 136 public static void testNewBufferedWriter (int lineNum) throws IOException {137 BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));138 while (--lineNum > 0) {139 newBufferedReader.write("写入文件Data\n");140 }141 newBufferedReader.close();142 }143 144 145 public static void main (String[] args) throws IOException {146 //多次测试时可清空result.txt文件147 FileWriter fileWriter = new FileWriter("./Result.txt");148 testDriver();149 }150 }
测试结果
从上图可以看出,写入行数超过20W以上时,FileOutputStream和NewOutputStream耗费时间远远超出其他4个类。为了清晰,让我们放大其他4个类的图:
可以看出,这4个类中,BufferWriter和NewBufferedWriter所耗费时间更少,但总体差别不是很大。
让我们再来看看,写入26W行数据以下时的情况:
可以看出,在数据量较小的情况下,这4个类所耗费时间的差异并不是很大,在更小的数据量下,它们的效率几乎没有差别。
后记
从以上分析可知(注意横坐标写入行数是指数级增加的),各个类的时间复杂度大致为O(k),其中不同的类的k不同,导致了最终巨大的差异。
这里只给出了测试结果,并未分析其底层实现原理,欢迎评论区留言。
另外,我没有在其他机器测试,有兴趣的小伙伴可以将自己的测试结果发出来,共同进步^_^
附件
本次测试数据结果(若看不清,可以下载到本地看)
原文出处:https://www.cnblogs.com/xiaoxi666/p/9531893.html
共同学习,写下你的评论
评论加载中...
作者其他优质文章