作为这个讨论的开始,这里有几个如何加速I/O的基本规则:

1. 避免访问磁盘

2. 避免访问底层的操作系统

3. 避免方法调用

4. 避免个别的处理字节和字符

很明显这些规则不能在所有的问题上避免,因为如果能够的话就没有实际的I/O被执行。考虑下面的计算文件中的新行符('\n')的三部分范例。

方法1: read方法

第一个方法简单的使用FileInputStream的read方法:

import java.io.*;

public class intro1 {

public static void main(String args[]) {

if (args.length != 1) {

System.err.println("missing filename");

System.exit(1);

}

try {

FileInputStream fis = new FileInputStream(args[0]);

int cnt = 0;

int b;

while ((b = fis.read()) != -1) {

if (b == '\n')

cnt++;

}

fis.close();

System.out.println(cnt);

} catch (IOException e) {

System.err.println(e);

}

}

}然而这个方法触发了大量的底层运行时系统调用--FileInputStream.read--返回文件的下一个字节的本机方法。

方法 2: 使用大缓冲区

第二种方法使用大缓冲区避免了上面的问题:

import java.io.*;

public class intro2 {

public static void main(String args[]) {

if (args.length != 1) {

System.err.println("missing filename");

System.exit(1);

}

try {

FileInputStream fis = new FileInputStream(args[0]);

BufferedInputStream bis = new BufferedInputStream(fis);

int cnt = 0;

int b;

while ((b = bis.read()) != -1) {

if (b == '\n')

cnt++;

}

bis.close();

System.out.println(cnt);

} catch (IOException e) {

System.err.println(e);

}

}

}

BufferedInputStream.read 从输入缓冲区获取下一个字节,仅仅只访问了一次底层系统。

方法 3: 直接缓冲

第三种方法避免使用 BufferedInputStream 而直接缓冲,因此排除了 read 方法的调用:

import java.io.*;

public class intro3 {

public static void main(String args[]) {

if (args.length != 1) {

System.err.println("missing filename");

System.exit(1);

}

try {

FileInputStream fis = new FileInputStream(args[0]);

byte buf[] = new byte[2048];

int cnt = 0;

int n;

while ((n = fis.read(buf)) != -1) {

for (int i = 0; i < n; i++) {

if (buf[i] == '\n')

cnt++;

}

}

fis.close();

System.out.println(cnt);

} catch (IOException e) {

System.err.println(e);

}

}

}

对于一个1 MB 的输入文件,以秒为单位的执行时间是:

intro1   6.9 intro2   0.9 intro3   0.4

或者说在最慢的方法和最快的方法间是17比1的不同。

这个巨大的加速并不能证明你应该总是使用第三种方法,即自己做缓冲。这可能是一个错误的倾向特别是在处理文件结束事件时没有仔细的实现。在可读性上它也没有其它方法好。但是记住时间花费在哪儿了以及在必要的时候如何矫正是很有用。

方法2 或许是对于大多应用的 "正确" 方法.

加速I/O的基本规则的更多相关文章

  1. javaIO缓冲区

    java中IO类分类. 图来自网络 缓冲区:应用程序在内存中开辟的一个空间.用来放置需要被写入或写出的数据. 使用缓冲区的 优点:使得应用程序操作磁盘(或者说是与磁盘的通信)的次数降低,提高应用程序的 ...

  2. java io性能分析

    摘要: 本文大多技术围绕调整磁盘文件 I/O,但是有些内容也同样适合网络 I/O 和窗口输出. 第一部分技术讨论底层的I/O问题,然后讨论诸如压缩,格式化和串行化等高级I/O问题.然而这个讨论没有包含 ...

  3. 百度MIP移动页面加速——不只是CDN

    MIP是用CDN做加速的么?准确答案是:是,但不只是. MIP全称Mobile Instant Pages,移动网页加速器,是百度提出的页面加速解决方案.MIP从前端渲染和页面网络传输两方面进行优化, ...

  4. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  5. 阿里云系列——6.给你的域名使用CDN加速(详细步骤+简单配置)

    网站部署之~阿里云系列汇总 http://www.cnblogs.com/dunitian/p/4958462.html 进入管理页面:https://home.console.aliyun.com/ ...

  6. Signalr系列之虚拟目录详解与应用中的CDN加速实战

    目录 对SignalR不了解的人可以直接移步下面的目录 SignalR系列目录 前言 前段时间一直有人问我 在用SignalR 2.0开发客服系统[系列1:实现群发通讯]这篇文章中的"/Si ...

  7. docker学习(2) mac中docker-machine使用vmware fusion以及配置国内镜像加速

    一.前言 先回顾下上一节创建docker-machine的过程,默认情况下docker toolbox中的docker-machine使用virtual box创建虚拟机,KI首次启动时创建虚拟机的过 ...

  8. [转]加速Android Studio/Gradle构建

    加速Android Studio/Gradle构建 android android studio gradle   已经使用Android Studio进行开发超过一年,随着项目的增大,依赖库的增多, ...

  9. 利用免费cdn加速webpack单页应用

    回顾现状 在之前的学习过程中,react单页应用经过webpack打包之后会输出大概如下的目录结构,它就是站点的所有前端组成了:   1 2 3 4 5 6 MacBook-Pro:output ba ...

随机推荐

  1. A-Z排序控件的实现

    前言 最近项目需要做一个地区首字母a-z排序的效果,记录一下自己如何实现的. 先看下效果图: 分析 这种效果自己实现还是第一次;之前见过这种效果: 这些字母都是onDraw画上去的;只要知道每个字母的 ...

  2. git push --set-upstream origin

    设置本地分支追踪远程分支 之后就可以直接使用git push提交代码

  3. ES6 let用法

    1.实现块作用域 2.不存在变量提升. ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域.凡是在声明之前就使用这些变量,就会报错.

  4. 【BIEE】存储安装信息的目录

    在BIEE中存在一个目录,用于存储BIEE的安装信息,这个文件的目录为 ~/Oracle_BI1/install/setupinfo.txt 我的目录为:E:/BIEE/Oracle_BI1/inst ...

  5. 应用zip压缩的javascript以及Egret H5游戏实战

    代码地址如下:http://www.demodashi.com/demo/11039.html 主要起因是策划对最快进入登录界面有硬性要求(3秒),那么最开始加载的文件越小越好.对H5的游戏程序进行压 ...

  6. 【微信小程序】微信小程序wx.previewImage预览图片

    一.小知识 二.例子,配合轮播图使用效果更佳!(如图1) 1.wxml <scroll-view scroll-y="true"> <swiper catchta ...

  7. CentOS7 升级到7.4

    2 升级CentOS7.4 自己电脑上的系统还是CentOS7.2,服务器是CentOS7.3, 打算统统升级到最新版 升级前查看 > lsb_release -a LSB Version: : ...

  8. iOS应用程序开发之应用间的跳转

    简介 配置和实现 判断应用启动方式 一.简介 最实际项目开发中,我们难免会遇到需要从一个应用跳转到另一个应用的情况.比如微信分享,实际就是一种应用间的跳转.但是有时候我们需要实现自己的两个应用间的跳转 ...

  9. LaTeX 中插入图片使其紧跟插入的文字之后

    LaTeX 中插入图片使其不跑到每页的开头而紧跟插入的文字之后. 此次建模过程中,遇到的一个比较棘手的问题是: 当插入图片时,图片的位置总是会自动跑到当页(或下一页)的最上方,而不是紧跟在其对应的说明 ...

  10. 编译的时候找不到包 但是maven denpendencies已经有这个包 。或者myeclipse 为webroot eclipse为webContext需要修改

    在Eclipse中生成项目是WebContent目录 而在MyEclipse中生成的项目目录名字好像叫做WebRoot,那么如果把MyEclipse的项目导入到Eclipse中,如果要部署项目到Tom ...