【问题标题】:How to increase io performances of this piece of code如何提高这段代码的io性能
【发布时间】:2014-07-31 12:49:43
【问题描述】:

我怎样才能使这段代码非常快? 它使用 RandomAccessFile (in) 读取原始图像并使用 DataOutputStream (out) 将其写入文件

final int WORD_SIZE = 4;
byte[] singleValue = new byte[WORD_SIZE];
long position;

    for (int i=1; i<=100000; i++)
    {
             out.writeBytes(i + " ");

             for(int j=1; j<=17; j++)
             {
                  in.seek(position);
                  in.read(singleValue);                     
                  String str = Integer.toString(ByteBuffer.wrap(singleValue).order(ByteOrder.LITTLE_ENDIAN).getInt());
                  out.writeBytes(str + " ");
                  position+=WORD_SIZE;      
             }
             out.writeBytes("\n");
    }

内部for每17个元素在文件中创建一个新行

谢谢

【问题讨论】:

  • 首先:删除 System.out :-)
  • @achingfingers 哈哈哈,谢谢 :)
  • DataOutputStream 之外使用BufferedOutputStream 以避免写入每个原始元素。
  • 另外你确定你需要RandomAccessFile吗?
  • 为每 4 个字节分配一个 ByteBuffer,这不是一个好主意。读取内存映射文件(通过ByteBuffer)应该更快。或者按照建议在BufferedOutputStream 周围使用DataOutputStream,并使用Integer.reverseBytes 更改字节顺序。

标签: java performance io random-access


【解决方案1】:

我认为你问的原因是因为这段代码运行得很慢。如果是这种情况,那么一个原因是每个seekread 调用都在进行系统调用。 RandomAccessFile 没有缓冲。 (我猜singleValue 是长度为 1 的 byte[]。)

因此,让这个过程更快的方法是退后一步,想想它实际上在做什么。如果我理解正确,它会读取文件中的每个第 4 个字节,将它们转换为十进制数字并将它们作为文本输出,17 到一行。您可以像这样使用BufferedInputStream 轻松做到这一点:

    int b = bis.read();  // read a byte
    bis.skip(3);         // skip 3 bytes.

(带有一些错误检查......)。如果你像这样使用BufferedInputStream,大多数readskip调用都会对已经缓冲的数据进行操作,系统调用的数量将每N字节减少到1,其中N是缓冲区大小。

更新 - 我的猜测是错误的。您实际上是在阅读替代词,所以...

    bis.read(singleValue);
    bis.skip(4);

每 100000 个偏移量我必须跳 200000,然后再做一次,直到文件结束。

使用bis.skip(800000) 来做到这一点。它应该通过移动文件位置而不实际读取任何数据来进行大跳跃。最多一个系统调用。 (至少对于FileInputStream。)


您还可以通过将DataOutputStream 包裹在BufferedOutputStream 周围来将输出端的速度提高大致相等的量。

但是System.out 已经被缓冲了。

【讨论】:

  • 我的 singleValue 是一个字节[4]。我读了 4 字节将它们转换为小端,然后保存结果
  • 完成,速度有点快。为了提高性能,我也做了out.writeBytes(Integer.toString(ByteBuffer.wrap(singleValue).order(ByteOrder.LITTLE_ENDIAN).getInt()) + " ");
  • 斯蒂芬 C 非常感谢
  • 我希望使用ByteBuffer 进行转换对整体性能影响不大。
  • 你也使用了 BufferedOutputStream 吗?摆脱 System.out 的东西?如果不尝试这两个。我预测会有很大的加速。
猜你喜欢
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多