性能

尽管“旧”的 I/O 流在用 nio 实现后性能有所提高,但是映射文件访问往往可以更加显著地
加快速度。下面的程序进行了简单的性能比较。


//: c12:MappedIO.java
// {Clean: temp.tmp}
import java.io.*;
import java.nio.*;
import java.nio.channels.*;


public class MappedIO {
    private static int numOfInts = 4000000;
    private static int numOfUbuffInts = 200000;
    private abstract static class Tester {
    private String name;
        public Tester(String name) { this.name = name; }
        public long runTest() { 
      System.out.print(name + ": ");
            try { 
        long startTime = System.currentTimeMillis();
        test();
        long endTime = System.currentTimeMillis();
        return (endTime - startTime);
            } catch (IOException e) { 
        throw new RuntimeException(e);
            } 
        } 
        public abstract void test() throws IOException;
    } 
    private static Tester[] tests = {  
    new Tester("Stream Write") {
      public void test() throws IOException {
        DataOutputStream dos = new DataOutputStream(
                    new BufferedOutputStream( 
                        new FileOutputStream(new File("temp.tmp")))); 
                for(int i = 0; i < numOfInts; i++)
                    dos.writeInt(i); 
                dos.close(); 
            } 
        },   
    new Tester("Mapped Write") {
      public void test() throws IOException {
                FileChannel fc =   
          new RandomAccessFile("temp.tmp", "rw")
          .getChannel();
        IntBuffer ib = fc.map( 
                    FileChannel.MapMode.READ_WRITE, 0, fc.size())
          .asIntBuffer();
                for(int i = 0; i < numOfInts; i++)
                    ib.put(i); 
                fc.close(); 
            } 
        },   
    new Tester("Stream Read") {
      public void test() throws IOException {
        DataInputStream dis = new DataInputStream(
                    new BufferedInputStream( 
                        new FileInputStream("temp.tmp"))); 
                for(int i = 0; i < numOfInts; i++)
          dis.readInt();
                dis.close(); 
            } 
        },   
    new Tester("Mapped Read") {
      public void test() throws IOException {
        FileChannel fc = new FileInputStream(
          new File("temp.tmp")).getChannel();
        IntBuffer ib = fc.map( 
                    FileChannel.MapMode.READ_ONLY, 0, fc.size())
          .asIntBuffer();
        while(ib.hasRemaining())
          ib.get();
                fc.close(); 
            } 
        },   
    new Tester("Stream Read/Write") {
      public void test() throws IOException {
        RandomAccessFile raf = new RandomAccessFile(
          new File("temp.tmp"), "rw");
                raf.writeInt(1); 
                for(int i = 0; i < numOfUbuffInts; i++) {
          raf.seek(raf.length() - 4);
                    raf.writeInt(raf.readInt()); 
                } 
                raf.close(); 
            } 
        },   
    new Tester("Mapped Read/Write") {
      public void test() throws IOException {
        FileChannel fc = new RandomAccessFile(
          new File("temp.tmp"), "rw").getChannel();
        IntBuffer ib = fc.map( 
                    FileChannel.MapMode.READ_WRITE, 0, fc.size())
          .asIntBuffer();
                ib.put(0); 
                for(int i = 1; i < numOfUbuffInts; i++)
                    ib.put(ib.get(i - 1)); 
                fc.close(); 
            } 
        } 
    }; 
    public static void main(String[] args) {
        for(int i = 0; i < tests.length; i++)
      System.out.println(tests[i].runTest()); 
    } 
} ///:~


正如在本书前面的例子中所看到的那样,runTest()是一个模板方法(Template Method),
为在匿名内部子类中定义的 test()的各种实现提供了测试框架。每种子类都将执行一种测
试,因此 test()方法为我们进行各种 I/O 操作提供了原型。


尽管映射写似乎要用到 FileOutputStream,但是映射文件中的所有输出必须使用
RandomAccessFile,正如前面程序代码中的读/写一样。


下面是一次运行的输出结果:


Stream Write: 1719
Mapped Write: 359
Stream Read: 750
Mapped Read: 125
Stream Read/Write: 5188
Mapped Read/Write: 16
注意 test()方法包括初始化各种 I/O 对象的时间,因此,即使建立映射文件的花费很大,

但是整体受益比起 I/O 流来说还是很显著的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值