欢迎光临
我们一直在努力

调整JavaTM 的I/O性能(二)(zt)-JSP教程,Java技巧及代码

建站超值云服务器,限时71元/月

格式化开销

实际上,将数据写入文件只是输出开销的一部分。另外一个巨大的开销是数据的格式 化。考虑下面的三个例 子,要求其输出如下的行:

the square of 5 is 25

方法 1

第一种方法是简单地输出一个固定串,以得到内部i/o开销的概念:

      public class format1 {

          public static void main(string args[]) {

              final int count = 25000;

              for (int i = 1; i <= count; i++) {

                  string s = "the square of 5 is 25\n";

                  system.out.print(s);

              }

          }

      }

方法 2

第二种方法采用带"+"的简单格式化:

      public class format2 {

          public static void main(string args[]) {

              int n = 5;

              final int count = 25000;

              for (int i = 1; i <= count; i++) {

                  string s = "the square of " + n + " is " + n * n + "\n";

                  system.out.print(s);

              }

          }

      }

方法 3

第三种方法使用了java.text包中的类messageformat:

      import java.text.*;

      public class format3 {

          public static void main(string args[]) {

              messageformat fmt =

                  new messageformat("the square of {0} is {1}\n");

              object values[] = new object[2];

              int n = 5;

              values[0] = new integer(n);

              values[1] = new integer(n * n);

              final int count = 25000;

              for (int i = 1; i <= count; i++) {

                  string s = fmt.format(values);

                  system.out.print(s);

              }

          }

      }

这些程序产生相同的输出,运行时间为:

      format1    1.3

      format2    1.8

      format3    7.8

最快和最慢之间的差距为6比1。如果该格式没有进行预编译,并且采用了便利的静态方法,第三个程序将更 慢。

方法 4

使用messageformat.format(string, object[])方法如下:

      import java.text.*;

      public class format4 {

          public static void main(string args[]) {

              string fmt = "the square of {0} is {1}\n";

              object values[] = new object[2];

              int n = 5;

              values[0] = new integer(n);

              values[1] = new integer(n * n);

              final int count = 25000;

              for (int i = 1; i <= count; i++) {

                  string s = messageformat.format(fmt, values);

                  system.out.print(s);

              }

          }

      }

这比前一个例子花费的时间还要长1/3。

方法3比1、2慢一点,并不意味不应该采用它。但是,应该明白在时间上的代价。

在国际化语言环境中,消息的格式是非常重要的,涉及到这个问题的应用程序通常从一个资源文件中读取该 格式,然后使用它。

随机存储

randomaccessfile是用于对文件进行随机i/o存储(在字节层次上)的一个java类。该类提供了一个与c/c++中 相似的搜索方法,以将文件指针移动到任意位置,然后就可以对从那里开始的字节进行读或写了。 该搜索方法访问底层的运行系统,正因为如此,开销可能非常昂贵。一个稍微廉价的替代方法是,在 randomaccessfile顶部设置自己的缓冲,并且实现对字节的直接读取方法。用于读取的参数是所需字节的字节 偏移量。下面的例子显示了这是如何进行的:

      import java.io.*;

      public class readrandom {

          private static final int default_bufsize = 4096;

          private randomaccessfile raf;

          private byte inbuf[];

          private long startpos = -1;

          private long endpos = -1;

          private int bufsize;

          public readrandom(string name)

                      throws filenotfoundexception {

              this(name, default_bufsize);

          }

          public readrandom(string name, int b)

                      throws filenotfoundexception {

              raf = new randomaccessfile(name, "r");

              bufsize = b;

              inbuf = new byte[bufsize];

          }

          public int read(long pos) {

              if (pos < startpos || pos > endpos) {

                  long blockstart = (pos / bufsize) * bufsize;

                  int n;

                  try {

                      raf.seek(blockstart);

                      n = raf.read(inbuf);

                  }

                  catch (ioexception e) {

                      return -1;

                  }

                  startpos = blockstart;

                  endpos = blockstart + n – 1;

                  if (pos < startpos || pos > endpos)

                      return -1;

              }

              return inbuf[(int)(pos – startpos)] & 0xffff;

          }

          public void close() throws ioexception {

              raf.close();

          }

          public static void main(string args[]) {

              if (args.length != 1) {

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

                  system.exit(1);

              }

              try {

                  readrandom rr = new readrandom(args[0]);

                  long pos = 0;

                  int c;

                  byte buf[] = new byte[1];

                  while ((c = rr.read(pos)) != -1) {

                      pos++;

                      buf[0] = (byte)c;

                      system.out.write(buf, 0, 1);

                  }

                  rr.close();

              }

              catch (ioexception e) {

                  system.err.println(e);

              }

          }

      }

本驱动器程序简单地顺序读取字节,并且输出。

如果拥有存储的局部性(在文件中相邻位置的字节可以被同时读取),那么这项技术很有帮助。例如,如果 在已排序的文件中实现二叉树搜索算法,此方法可能很有用。如果在一个大文件中的任意位置进行随机存 储,其价值较小。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 调整JavaTM 的I/O性能(二)(zt)-JSP教程,Java技巧及代码
分享到: 更多 (0)