• 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好
  • 相关阅读:
    JSON.parse与eval
    加密算法
    asp.net权限管理
    asp.net登录状态验证
    U3D Debug.log的问题
    yield(C# 参考)
    U3D 动态创建Prefab的多个实例
    U3D事件系统总结
    C#事件与接口
    C#泛型委托,匿名方法,匿名类
  • 原文地址:https://www.cnblogs.com/zhangshiwen/p/4802461.html
Copyright © 2020-2023  润新知