作为这个讨论的开始,这里有几个如何加速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. IOS 开发学习33 使用sqlite3

    sqlite3 命令行简单使用 sqlite3 路径 //打开数据库路径连接 select * from sqlite_master where type="table"; //显 ...

  2. 解决游戏server负载上限问题

    近期开发一款网络游戏,快到公布阶段.可是server的负载上限问题,这个该怎么处理呢? 如今有下面几种方案: 1.排队机制,像wow那样: 2.给当已满服打上一个"满"标记,不让玩 ...

  3. C#中使用正则

      using System.Text.RegularExpressions;           private void button1_Click(object sender, EventArg ...

  4. MySql sqlstate代码大全(转载)

    http://blog.csdn.net/u013847120/article/details/52887813 本章列出了当你用任何主机语言调用MySQL时可能出现的错误.首先列出了服务器错误消息. ...

  5. 禁止 git 自动转换换行符

    开发团队都在 windows 下开发,有IDE管理代码.对我们来说,最好是禁用换行转换符的功能.我用 cygwin 提交代码,提交时总提示自动转换换符.其实都不用提交,仅运行 git status 看 ...

  6. 如何为Drupal缓存对象指定缓存类?

    什么意思?意思是说,假如你有这样的需求,需要将cache_page缓存到数据库,其它的都缓存到memcache,这该怎么办? 看看_cache_get_object()的实现你就会知道上面的问题该怎么 ...

  7. 哪种代理适合用于Web数据采集

    在Web数据采集中为了避免被服务器封锁而通过代理下载的情况很常见.但是,并非所有的代理都适合于Web数据采集.下面是鲲鹏数据的技术人员给出的说明. 根据HTTP代理的匿名性可以将其分为以下几种:   ...

  8. iTunes 无法添加 iPhone 自定义铃声

    本篇文章由:http://xinpure.com/itunes-unable-to-add-iphone-custom-ringtones/ 新版本 iTunes 需要在 菜单栏 -> 文件 中 ...

  9. django inspectdb

    使用inspectdb  --通过已有数据库表生成 model.pyinspectdb辅助工具检查你的settings文件指向的数据库,决定你表示你的表的Django模型并打印Python模型代码到标 ...

  10. Linux命令-网络命令:netstat

    netstat -tlun 查看本机监听tcp.udp显示IP地址和端口号 netstat -an 可以查看本机正在连接的所有信息 netstat -rn 可以查看本机网关 windows里面的net ...