【问题标题】:does channels slow the read?频道会减慢阅读速度吗?
【发布时间】:2015-02-10 00:32:15
【问题描述】:

我的印象是使用 FileChannel 和 ByteBuffer 会加快读取时间,但它似乎比从文件流中读取要慢得多。我在这里做错了吗?

FileInputStream fis = new FileInputStream("C:\\Users\\blah\\Desktop\\del\\pg28054.txt");
        FileOutputStream fos = new FileOutputStream("C:\\Users\\blah\\Desktop\\del\\readme.txt");

        FileChannel fcin = fis.getChannel();
        FileChannel fcout = fos.getChannel();

        ByteBuffer buffer = ByteBuffer.allocate(1024);
        long startTime = System.currentTimeMillis();
        long endtime = System.currentTimeMillis();
        while(true){
            buffer.clear();
            int r = fcin.read(buffer);
            if(r==-1){
                break;
            }
            buffer.flip();
            fcout.write(buffer);
        }
        endtime = System.currentTimeMillis();
        System.out.println("time to read and write(ms) " + (endtime - startTime));

以上在 108 毫秒内完成,而以下实现在 43 毫秒内完成

        long startTime;
        long endtime;
        FileInputStream fis1 = new FileInputStream("C:\\Users\\blah\\Desktop\\del\\pg28054.txt");
        FileOutputStream fos1 = new FileOutputStream("C:\\Users\\blah\\Desktop\\del\\readme1.txt");

        byte b[] = null;

        startTime = System.currentTimeMillis();
        while(true){
            b = new byte[1024];
            int r = fis1.read(b);
            if(r==-1){
                break;
            }
            fos1.write(b);
        }

        endtime = System.currentTimeMillis();
        System.out.println("time to read and write(ms) " + (endtime - startTime));

【问题讨论】:

  • 微基准测试的常见问题是:您是否在 JVM 中多次运行实验,让 JIT 有足够的时间完成其工作?您是否使用--XX:+PrintCompilation 来确认 JIT 对于您使用其值的运行是安静的?一个直接的想法是,第一个代码块可能会引入更多的类(这需要更大的开销),即使这些类在经过 JIT 等处理后会产生更快的代码。
  • 多一点信息会更好 - 你的文件有多大。你是如何运行你的基准测试的。
  • 您究竟从哪里得到的印象是这个案子应该更快?注意你的复制循环都是无效的。 NIO 循环应该调用compact() 而不是clear(),java.io 循环应该调用fos1.write(b, 0, r)。否则会有数据丢失的风险。
  • 在您的第二次测试中,您不一定写出正确的数据。你应该打电话给fos1.write(b,0,r),而不是fos1.write(b)

标签: java nio


【解决方案1】:

除了关于基准质量的非常准确的 cmets 之外,没有任何关于 Channels 或 ByteBuffers 本质上比流更快的内容。有一些选项可以使事情执行得更快。例如,您可以使用FileChannel.transferFrom 方法来传输内容。另一个例子是使用direct ByteBuffer 来传输内容。

【讨论】:

    猜你喜欢
    • 2011-12-14
    • 2014-07-03
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多