调整JavaTM 的I/O性能(三)(zt)

性能

压缩

Java提供了对字节流进行压缩和解压缩的类。它们可以在java.util.zip包中被找到,同时也作为Jar文件的基 础(Jar文件是具有一个清单的Zip文件)。

以下的程序采用一个单一的输入文件,并且生成一个压缩了的Zip输出文件,该程序带有一个表示输入文件的 入口项。

      import java.io.*;

      import java.util.zip.*;

      public class compress {

          public static void doit(String filein, String fileout) {

              FileInputStream fis = null;

              FileOutputStream fos = null;

              try {

                  fis = new FileInputStream(filein);

                  fos = new FileOutputStream(fileout);

                  ZipOutputStream zos = new ZipOutputStream(fos);

                  ZipEntry ze = new ZipEntry(filein);

                  zos.putNextEntry(ze);

                  final int BUFSIZ = 4096;

                  byte inbuf[] = new byte[BUFSIZ];

                  int n;

                  while ((n = fis.read(inbuf)) != -1)

                      zos.write(inbuf, 0, n);

                  fis.close();

                  fis = null;

                  zos.close();

                  fos = null;

              }

              catch (IOException e) {

                  System.err.println(e);

              }

              finally {

                  try {

                      if (fis != null)

                          fis.close();

                      if (fos != null)

                          fos.close();

                  }

                  catch (IOException e) {

                  }

              }

          }

          public static void main(String args[]) {

              if (args.length != 2) {

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

                  System.exit(1);

              }

              if (args[0].equals(args[1])) {

                  System.err.println("filenames are identical");

                  System.exit(1);

              }

              doit(args[0], args[1]);

          }

      }

下一个程序正好相反,采用假定只有一个入口项的Zip输入文件,并且将该项解压到指定的输出文件:

      import java.io.*;

      import java.util.zip.*;

      public class uncompress {

          public static void doit(String filein, String fileout) {

              FileInputStream fis = null;

              FileOutputStream fos = null;

              try {

                  fis = new FileInputStream(filein);

                  fos = new FileOutputStream(fileout);

                  ZipInputStream zis = new ZipInputStream(fis);

                  ZipEntry ze = zis.getNextEntry();

                  final int BUFSIZ = 4096;

                  byte inbuf[] = new byte[BUFSIZ];

                  int n;

                  while ((n = zis.read(inbuf, 0, BUFSIZ)) != -1)

                      fos.write(inbuf, 0, n);

                  zis.close();

                  fis = null;

                  fos.close();

                  fos = null;

              }

              catch (IOException e) {

                  System.err.println(e);

              }

              finally {

                  try {

                      if (fis != null)

                          fis.close();

                      if (fos != null)

                          fos.close();

                  }

                  catch (IOException e) {

                  }

              }

          }

          public static void main(String args[]) {

              if (args.length != 2) {

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

                  System.exit(1);

              }

              if (args[0].equals(args[1])) {

                  System.err.println("filenames are identical");

                  System.exit(1);

              }

              doit(args[0], args[1]);

          }

      }

压缩是有助还是损害I/O性能很大程度上依赖于本地硬件设置;尤其是处理器和磁盘驱动器的相对速度。采用 Zip技术进行压缩,典型地将数据量减少50%,但是有一些压缩和解压的时间开销。在带IDE磁盘驱动器的 300-MHz Pentium PC上,对一个大的压缩文本文件(5-10MB)的实验表明,从磁盘读取压缩文件比非压缩文件 快将近1/3。

充分展现压缩优越性的一个例子是在写入象软盘这样的低速介质。使用高速处理器 (300 MHz Pentium)和低 速软盘(PC上常用的软盘驱动器)进行的测试显示,压缩一个大文本文件,然后写入软盘,比直接将文件拷 贝到软盘快50%。

高速缓存

关于硬件的高速缓存的详细讨论超出了本文的范围。但是,有时软件高速缓存 能够加速I/O。考虑这样一个 例子,需要以随机的方式读取文本文件的某些行。完成的方法之一是读入所有的行,并且把它们存储在 ArrayList(一个与Vector相似的collection类)中:

      import java.io.*;

      import java.util.ArrayList;

      public class LineCache {

          private ArrayList list = new ArrayList();

          public LineCache(String fn) throws IOException {

              FileReader fr = new FileReader(fn);

              BufferedReader br = new BufferedReader(fr);

              String ln;

              while ((ln = br.readLine()) != null)

                  list.add(ln);

              br.close();

          }

          public String getLine(int n) {

              if (n < 0)

                  throw new IllegalArgumentException();

              return (n < list.size() ?

                  (String)list.get(n) : null);

          }

          public static void main(String args[]) {

              if (args.length != 1) {

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

                  System.exit(1);

              }

              try {

                  LineCache lc = new LineCache(args[0]);

                  int i = 0;

                  String ln;

                  while ((ln = lc.getLine(i++)) != null)

                      System.out.println(ln);

              }

              catch (IOException e) {

                  System.err.println(e);

              }

          }

      }

getLine方法被用来检索任意的一行。这项技术非常有用,但对于大文件而言,显然需要使用了大量的内存, 因此具有局限性。一个替代方法是仅仅记住最近被请求的100行,必要时从磁盘上读取其他行。在存在行的存 储局部性这种情况下,这个方案运行良好,但是需要真正的随机存储时就没有这么好了。

标志化(Tokenization)

标志化(Tokenization)指将字节或者字符序列拆散成象词一样的逻辑块的过程。Java提供了StreamTokenizer 类,可以进行如下的操作:

      import java.io.*;

      public class token1 {

          public static void main(String args[]) {

              if (args.length != 1) {

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

                  System.exit(1);

              }

              try {

                  FileReader fr = new FileReader(args[0]);

                  BufferedReader br = new BufferedReader(fr);

                  StreamTokenizer st = new StreamTokenizer(br);

                  st.resetSyntax();

                  st.wordChars('a', 'z');

                  int tok;

                  while ((tok = st.nextToken()) !=

                              StreamTokenizer.TT_EOF) {

                      if (tok == StreamTokenizer.TT_WORD)

                          ; // st.sval has token

                  }

                  br.close();

              }

              catch (IOException e) {

                  System.err.println(e);

              }

          }

      }

本例根据小写字母(字母a-z)进行标记。如果由您自己实现了其等效程序,可能看上去象这样:

      import java.io.*;

      public class token2 {

          public static void main(String args[]) {

              if (args.length != 1) {

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

                  System.exit(1);

              }

              try {

                  FileReader fr = new FileReader(args[0]);

                  BufferedReader br = new BufferedReader(fr);

                  int maxlen = 256;

                  int currlen = 0;

                  char wordbuf[] = new char[maxlen];

                  int c;

                  do {

                      c = br.read();

                      if (c >= 'a' && c <= 'z') {

                          if (currlen == maxlen) {

                              maxlen *= 1.5;

                              char xbuf[] =

                                  new char[maxlen];

                              System.arraycopy( wordbuf, 0,

                                              xbuf, 0, currlen);

                              wordbuf = xbuf;

                          }

                          wordbuf[currlen++] = (char)c;

                      }

                      else

                          if (currlen > 0) {

                              String s = new String(wordbuf, 0,

                                              currlen);

                              // do something with s

                              currlen = 0;

                          }

                  } while (c != -1);

                  br.close();

              }

              catch (IOException e) {

                  System.err.println(e);

              }

          }

      }

时间: 2024-10-30 04:29:48

调整JavaTM 的I/O性能(三)(zt)的相关文章

调整JavaTM 的I/O性能(一)(zt)

性能 调整JavaTM 的I/O性能这篇文章讨论并举例阐述了提高JavaTM I/O性能的多种技术.绝大多数技术是围绕着磁盘文件I/O的调整来谈 的,但是,有些技术对网络I/O和视窗输出也同样适用.首先介绍的技术包含底层I/O问题,然后对诸如压 缩.格式化和序列化这样的高层I/O进行讨论.但是,请注意,本讨论不涉及应用设计问题, 搜索算法和数 据结构的选择,也不讨论类似文件高速缓存(file caching)这样的系统级问题. 当讨论Java I/O时,Java编程语言所假定的两种不同的磁盘文件

调整JavaTM 的I/O性能(四)(zt)

性能 第二个程序比第一个大约快20%,代价是不得不写一些技巧性的底层代码. StreamTokenizer是一个杂和的类,因为它从基于字符的流中读取(象BufferedReader)数据,但同时又以字节进 行操作,即尽管它们是字母,也要用两字节的值来处理所有的字符(大于0xff). 序列化 序列化使用一个标准格式,将任意一个Java数据结构转换为字节流.例如,如下程序输出一个随机的整数数 组:       import java.io.*;       import java.util.*;  

调整JavaTM 的I/O性能(二)(zt)

性能 格式化开销 实际上,将数据写入文件只是输出开销的一部分.另外一个巨大的开销是数据的格式 化.考虑下面的三个例 子,要求其输出如下的行: The square of 5 is 25 方法 1 第一种方法是简单地输出一个固定串,以得到内部I/O开销的概念:       public class format1 {           public static void main(String args[]) {               final int COUNT = 25000;  

Oracle如何调整RMAN备份与恢复操作的性能

RMAN 实际上即装即用的,我们通常不需要对其做什么调整. 但是,RMAN 体系结构中还包含许多组件,当这些组件构成一个整体时,就必须调整RMAN的设置以从备份进程中得到最佳的性能. 通常RMAN 调整设计到处理逻辑和物理数据库设计中的低效率,调整介质管理库(Media Management Library: MML), 调整RMAN 和MML 层以备份数据库的物理设备更好地共存. 一. 调整RMAN 前的工作 如果RMAN 的备份操作时间非常长,这可能不是RMAN的故障. 在大多数情况下,这可

调整Oracle数据库服务器的性能技巧

oracle是殷墟(Yin Xu)出土的甲骨文(oracle bone inscriptions)的英文翻译的第一个单词,在英语里是"神谕"的意思. 与无压缩格式下http://www.aliyun.com/zixun/aggregation/17326.html">存储数据相比,新的Oracle数据压缩技术能够确保以较小的开销节省三倍以上的磁盘存储空间.这一点比仅节省磁盘空间要具有更大的优势,因为它能够使企业节约更多的开支,以便有更多的资金来巩固自己的地位.自动诊断知

全球超算竞赛性能“三冠王”领衔超算服务器

[天极网服务器频道12月16日消息]美国丹佛当地时间11月19日,在此间举行的SC13全球超算大会Top500颁奖仪式上,组委会公布来自中国的国防科学技术大学参赛队以每秒8.22万亿次的Linpack成绩取得SC 13全球大学生超级计算机竞赛最高计算性能,这也是国防科大继ISC 12.SC 12之后第三次荣登该项成绩冠军. 作为"最高计算性能奖"的卫冕冠军,国防科学技术大学在比赛中设计了由8台浪潮NF5280 M3服务器为计算节点的超算系统,并采用了"C+G"混合架

Oracle性能调整的指导纲要

讲优化时大致写的一个提纲,内容分db的物理设计和逻辑设计,主要以物理设计为主,逻辑设计介绍的内容不多,提纲里把物理结构设计和实例优化有机的结合在一起,把逻辑结构设计和应用调整结合在一起...... Oracle性能调整指导纲要 数据库物理结构设计和实例级别的调整 一.Oracle性能优化方法论 1.为什么(what)要优化(系统慢了?慢是表象) 2.怎样(how)优化?(需要找到慢的原因) a.是系统的问题? b.是数据库的问题? 3.谁(who)来优化? a.系统架构师(系统架构设计的有问题,

数据库性能分析及调整一例

数据|数据库|性能 故障现象2004年6月8日上午10:00,内蒙古巴盟网通用户反映在OSS系统界面"话单查询"里查询单个用户五天的话单特别慢,查询很长时间无结果. 例如:在OSS系统界面"综合查询"内点击"收费"-〉"话单查询",键入"用户号码,起始时间:2004-01-01 00:00:00,结束时间:2004-06-01 23:00:00",点击查询后,IE进度条缓慢,很长时间不返回结果.故障分析经过

asp性能测试报告(转)(三)

性能 三.启用缓冲对性能的影响有多大? 如果启用缓冲,则在整个页面处理完毕之前服务器不会向浏览器发送页面内容.缓冲可以通过两种方式启用:通过在ASP页面内设置Response.Buffer属性,或通过服务器设置.下面分别测试这两种方法. 3.1 通过脚本启用缓冲 在ASP脚本的前面加入Response.Buffer=True,IIS将缓冲页面内容: < % OPTION EXPLICIT Response.Buffer = trueDim FirstName.../app1/buffer__1.