热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java文件操作类效率对比

nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd

前言

众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例:

面向字节流的:FileOutputStream 和 BufferedOutputStream

面向字符流的:FileWriter 和 BufferedWriter

近年来发展出New I/O ,也叫NIO,里面又包装了两个类:NewOutputStream 和 NewBufferedWriter

现在,我们建立测试程序,比较这些类写入文件的性能。

机器配置

  • 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的次方指数级增长行数

import java.io.File;
import java.io.FileOutputStream;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class testFileIO {

    public static void testDriver () throws IOException {
        int maxlineNum = 100000001;//写入文件的最大行数
        int startlineNum = 1;//写入文件的行数
        int Multiplying = 2;//行数增长倍率

        long begin = 0L;
        long end = 0L;

        //将时间统计写入文件Result.txt中
        FileWriter fileWriter = new FileWriter("./Result.txt", true);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

        System.out.println("Test FileOutputStream begin.");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testFileOutputStream(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_FileOutputStream = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t");
        }
        System.out.println("Test FileOutputStream end.\n");

        System.out.println("Test BufferedOutputStream begin.");
        bufferedWriter.write("\n");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testBufferedOutputStream(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_BufferedOutputStream = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t");
        }
        System.out.println("Test BufferedOutputStream end.\n");

        System.out.println("Test FileWriter begin.");
        bufferedWriter.write("\n");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testFileWriter(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_FileWriter = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t");
        }
        System.out.println("Test FileWriter end.\n");

        System.out.println("Test BufferedWriter begin.");
        bufferedWriter.write("\n");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testBufferedWriter(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_BufferedWriter = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t");
        }
        System.out.println("Test BufferedWriter end.\n");

        System.out.println("Test NewOutputStream begin.");
        bufferedWriter.write("\n");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testNewOutputStream(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_NewOutputStream = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t");
        }
        System.out.println("Test NewOutputStream end.\n");

        System.out.println("Test NewBufferedWriter begin.");
        bufferedWriter.write("\n");
        for (int lineNum = startlineNum; lineNum             begin = System.currentTimeMillis();
            testNewBufferedWriter(lineNum);
            end = System.currentTimeMillis();
            long timeElapse_NewBufferedWriter = end - begin;
            bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t");
        }
        System.out.println("Test NewOutputStream end.\n");

        bufferedWriter.close();
    }

    /************************** I/O *****************************/
    //面向字节
    public static void testFileOutputStream (int lineNum) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
        while (--lineNum > 0) {
            fileOutputStream.write("写入文件Data\n".getBytes());
        }
        fileOutputStream.close();
    }

    public static void testBufferedOutputStream (int lineNum) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        while (--lineNum > 0) {
            bufferedOutputStream.write("写入文件Data\n".getBytes());
        }
        bufferedOutputStream.close();
    }

    //面向字符
    public static void testFileWriter (int lineNum) throws IOException {
        FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
        while (--lineNum > 0) {
            fileWriter.write("写入文件Data\n");
        }
        fileWriter.close();
    }

    public static void testBufferedWriter (int lineNum) throws IOException {
        FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        while (--lineNum > 0) {
            bufferedWriter.write("写入文件Data\n");
        }
        bufferedWriter.close();
    }


    /************************** NIO ****************************/
    public static void testNewOutputStream (int lineNum) throws IOException {
        OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
        while (--lineNum > 0) {
            outputStream.write("写入文件Data\n".getBytes());
        }
        outputStream.close();
    }

    public static void testNewBufferedWriter (int lineNum) throws IOException {
        BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
        while (--lineNum > 0) {
            newBufferedReader.write("写入文件Data\n");
        }
        newBufferedReader.close();
    }


    public static void main (String[] args) throws IOException {
        //多次测试时可清空result.txt文件
        FileWriter fileWriter = new FileWriter("./Result.txt");
        testDriver();
    }
}

测试结果

#

从上图可以看出,写入行数超过20W以上时,FileOutputStream和NewOutputStream耗费时间远远超出其他4个类。为了清晰,让我们放大其他4个类的图:

 

#

可以看出,这4个类中,BufferWriter和NewBufferedWriter所耗费时间更少,但总体差别不是很大。

让我们再来看看,写入26W行数据以下时的情况:

     #

 可以看出,在数据量较小的情况下,这4个类所耗费时间的差异并不是很大,在更小的数据量下,它们的效率几乎没有差别。

后记

从以上分析可知(注意横坐标写入行数是指数级增加的),各个类的时间复杂度大致为O(1/kn),其中不同的类的k不同,导致了最终巨大的差异。

这里只给出了测试结果,并未分析其底层实现原理,欢迎评论区留言。

另外,我没有在其他机器测试,有兴趣的小伙伴可以将自己的测试结果发出来,共同进步^_^

附件

本次测试数据结果(若看不清,可以下载到本地看)

#

 


推荐阅读
  • 本文详细介绍了如何在 Ubuntu 14.04 系统上搭建仅使用 CPU 的 Caffe 深度学习框架,包括环境准备、依赖安装及编译过程。 ... [详细]
  • 使用Python构建网页版图像编辑器
    本文详细介绍了一款基于Python开发的网页版图像编辑工具,具备多种图像处理功能,如黑白转换、铅笔素描效果等。 ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 本文介绍了如何使用 Python 的 Pyglet 库加载并显示图像。Pyglet 是一个用于开发图形用户界面应用的强大工具,特别适用于游戏和多媒体项目。 ... [详细]
  • 本文探讨了Python中的enchant模块及其提供的dict_exists()函数,该函数用于检测特定语言词典的可用性。 ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
  • 2019年独角兽企业招聘Python工程师标准课程概览
    本文详细介绍了2019年独角兽企业在招聘Python工程师时的标准课程内容,包括Shell脚本中的逻辑判断、文件属性判断、if语句的特殊用法及case语句的应用。 ... [详细]
  • 【MySQL】frm文件解析
    官网说明:http:dev.mysql.comdocinternalsenfrm-file-format.htmlfrm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果 ... [详细]
  • 解析Java虚拟机HotSpot中的GC算法实现
    本文探讨了Java虚拟机(JVM)中HotSpot实现的垃圾回收(GC)算法,重点介绍了根节点枚举、安全点及安全区域的概念和技术细节,以及这些机制如何影响GC的效率和准确性。 ... [详细]
  • WebBenchmark:强大的Web API性能测试工具
    本文介绍了一款名为WebBenchmark的Web API性能测试工具,该工具不仅支持HTTP和HTTPS服务的测试,还提供了丰富的功能来帮助开发者进行高效的性能评估。 ... [详细]
  • 本文探讨了异步编程的发展历程,从最初的AJAX异步回调到现代的Promise、Generator+Co以及Async/Await等技术。文章详细分析了Promise的工作原理及其源码实现,帮助开发者更好地理解和使用这一重要工具。 ... [详细]
  • 本文探讨了Python类型注解使用率低下的原因,主要归结于历史背景和投资回报率(ROI)的考量。文章不仅分析了类型注解的实际效用,还回顾了Python类型注解的发展历程。 ... [详细]
author-avatar
广东淡水未央
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有