1.深入分析_NIO性能分析

首先还是看一个用3中方式copy文件的测试Demo

分别是:普通Stream文件copy,BuffferedStream进行Copy 和Channel(nio)进行文件Copy的代码和性能测试报告:

  1 package com.ctyun.stream;
  2 
  3 import java.io.BufferedInputStream;
  4 import java.io.BufferedOutputStream;
  5 import java.io.File;
  6 import java.io.FileInputStream;
  7 import java.io.FileNotFoundException;
  8 import java.io.FileOutputStream;
  9 import java.io.IOException;
 10 import java.nio.channels.FileChannel;
 11 /**
 12  * 
 13  * @Description    文件效率copy测试
 14  * @author         zhanghw@chinatelecom.com.cn
 15  * @since          2015年9月11日
 16  * @version        V1.0
 17  */
 18 public class FileCopyEfficientTest {
 19     
 20     //普通io流copy
 21     public static void commonCopy(String source, String dest){
 22         FileInputStream in = null;
 23         FileOutputStream out = null;
 24         try {
 25             in = new FileInputStream(new File(source));
 26             out = new FileOutputStream(new File(dest));
 27             
 28             byte[] b = new byte[2048];
 29             while(in.read(b) != -1  ){
 30                 out.write(b);
 31             }
 32             out.flush();
 33             
 34         } catch (FileNotFoundException e) {
 35             e.printStackTrace();
 36         } catch (IOException e) {
 37             // TODO Auto-generated catch block
 38             e.printStackTrace();
 39         }finally{
 40             try {
 41                 if(in != null){
 42                     in.close();
 43                 }
 44                 if(out != null){
 45                     out.close();
 46                 }
 47             } catch (IOException e) {
 48                 // TODO Auto-generated catch block
 49                 in = null;
 50                 out =null;
 51                 e.printStackTrace();
 52             }
 53         }
 54     }
 55     
 56     //Streambuffer进行copy
 57     public static void bufferCopy(String source, String dest){
 58         FileInputStream in = null;
 59         FileOutputStream out = null;
 60         BufferedInputStream bufferedIn = null;
 61         BufferedOutputStream bufferedOut = null;
 62         
 63         try {
 64             in = new FileInputStream(new File(source));
 65             out = new FileOutputStream(new File(dest));
 66             
 67             bufferedIn = new BufferedInputStream(in);
 68             bufferedOut = new BufferedOutputStream(out);
 69             
 70             byte[] b = new byte[2048];
 71             while(bufferedIn.read(b) != -1  ){
 72                 bufferedOut.write(b);
 73             }
 74             bufferedOut.flush();
 75             
 76         } catch (FileNotFoundException e) {
 77             e.printStackTrace();
 78         } catch (IOException e) {
 79             // TODO Auto-generated catch block
 80             e.printStackTrace();
 81         }finally{
 82             try {
 83                 if(in != null){
 84                     in.close();
 85                 }
 86                 if(out != null){
 87                     out.close();
 88                 }
 89                 if(bufferedIn != null){
 90                     bufferedIn.close();
 91                 }
 92                 if(bufferedOut != null){
 93                     bufferedOut.close();
 94                 }
 95             } catch (IOException e) {
 96                 // TODO Auto-generated catch block
 97                 in = null;
 98                 out =null;
 99                 bufferedIn = null;
100                 bufferedOut = null;
101                 e.printStackTrace();
102             }
103         }
104     }
105     
106     //用Channel进行copy
107     public static void channelCopy(String source, String dest){
108         FileInputStream in = null;
109         FileOutputStream out = null;
110         FileChannel channelIn = null;
111         FileChannel channelOut = null;
112         
113         try {
114             in = new FileInputStream(new File(source));
115             out = new FileOutputStream(new File(dest));
116             channelIn = in.getChannel();
117             channelOut = out.getChannel();
118             
119             channelIn.transferTo(0, channelIn.size(), channelOut);
120             
121         } catch (FileNotFoundException e) {
122             e.printStackTrace();
123         } catch (IOException e) {
124             // TODO Auto-generated catch block
125             e.printStackTrace();
126         }finally{
127             try {
128                 if(in != null){
129                     in.close();
130                 }
131                 if(out != null){
132                     out.close();
133                 }
134                 if(channelIn != null){
135                     channelIn.close();
136                 }
137                 if(channelOut != null){
138                     channelOut.close();
139                 }
140                 
141             } catch (IOException e) {
142                 // TODO Auto-generated catch block
143                 in = null;
144                 out =null;
145                 channelIn = null;
146                 channelOut = null;
147                 e.printStackTrace();
148             }
149         }
150         
151     }
152     
153     //测试因为会线程原因,造成时间不正确
154     /*public static void main(String[] args) {
155         String source = "d:/test.txt";
156         String dest1 = "d:/temp/test1.txt";
157         String dest2 = "d:/temp/test2.txt";
158         String dest3 = "d:/temp/test3.txt";
159         
160         long l1 = System.currentTimeMillis();
161         commonCopy(source, dest1);
162         long l2 = System.currentTimeMillis();
163         System.out.println("普通Stream Copy用时:"+(l2-l1));
164         
165         bufferCopy(source, dest2);
166         long l3 = System.currentTimeMillis();
167         System.out.println("buffer Stream Copy用时:"+(l3-l2));
168         
169         channelCopy(source, dest3);
170         long l4 = System.currentTimeMillis();
171         System.out.println("channel Stream Copy用时:"+(l4-l3));
172         
173     }*/
174     
175     public static void main(String[] args) {
176         String source = "d:/test.txt";
177         String dest = "d:/temp/test1.txt";
178         
179         long l1 = System.currentTimeMillis();
180 //        commonCopy(source, dest);
181         bufferCopy(source, dest);
182 //        channelCopy(source, dest);
183         long l2 = System.currentTimeMillis();
184         System.out.println("Copy用时:"+(l2-l1));
185         
186     }
187 
188 }
View Code

 性能测试结果及结论:

测试1:不同文件大小测试时间(在同一main函数中进行测试)

大小普通Copy(毫秒)
BufferCopy(毫秒)
ChannelCopy(毫秒)
文件类型
1m
56
44
72  
文本
128m
2095
1132  
437
文本
512m
9215
6710
10444
文本
1g
19989 
49358  
44809
文本
2g
69266
63989
58310
文本
 
结论:通过观察发现此次测试结果之间差异非常大,并且笔者在观察文件copy时,并没有按照正常顺序进行copy,所以(猜测)可能是在同一main方法中因为线程资源不均衡问题,造成测试结果差异较大, 不准确(copy文件之间存在干扰)。
为证实以上结论继续如下测试:

测试2:在同一main函数中进行测试
1024M多次测试结果
测试次数
大小普通Copy(毫秒)
BufferCopy(毫秒)
ChannelCopy(毫秒)
文件类型
1
1g
17365 
34371
27906  
文本
2
1g
39903 
35203  
19079
文本
3
1g
43865 
36720
28984
文本
--------------------------------------
结论:每次性能差异很大,原因可能是(猜测):在同一个main方法中由于文件流操作时线程获取cup资源的时间不同造成 (copy文件之间存在干扰),
为了保证测试的准确性,修改测试为没法方法在main方法中单独测试。

单独测试,在一个个main方法运行时,保证只有一个copy方法运行(最终测试方案,正确)(copy文件之间相互独立,不存在干扰)

大小普通Copy(毫秒)
BufferCopy(毫秒)
ChannelCopy(毫秒)
文件类型
1m
62
16
31
文本
128m
1953
907
422
文本
512m
8126
3422
1141
文本
1g
86944
87572
17703
文本
2g
66079
55298
17219
文本
 
测试次数
大小普通Copy(毫秒)
BufferCopy(毫秒)
ChannelCopy(毫秒)
文件类型
1
1g
15281
8937
5860
文本
2
1g
15485
7203
5703
文本
3
1g
16068
6828
5422
文本
 
结论: 在通常情况下,nio的性能>buffered性能>普通Stream的性能,但是在小文件的时候Buffered性能会比nio好

转载于:https://www.cnblogs.com/zhangshiwen/p/4802461.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值