用Java编写整数数组到文件的最快方法?

正如标题所说,我正在寻找将整数数组写入文件的最快速方法.阵列的大小会有所不同,并且实际上可以包含2500到25 000 000个内部的任何地方.

以下是我目前使用的代码

DataOutputStream writer = new DataOutputStream(new bufferedoutputstream(new FileOutputStream(filename)));

for (int d : data)
  writer.writeInt(d);

鉴于DataOutputStream有一个写入字节数组的方法,我已经尝试将int数组转换为字节数组,如下所示:

private static byte[] integersToBytes(int[] values) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    for (int i = 0; i < values.length; ++i) {
        dos.writeInt(values[i]);
    }

    return baos.toByteArray();
}

就像这样:

private static byte[] integersToBytes2(int[] src) {
    int srcLength = src.length;
    byte[] dst = new byte[srcLength << 2];

    for (int i = 0; i < srcLength; i++) {
        int x = src[i];
        int j = i << 2;
        dst[j++] = (byte) ((x >>> 0) & 0xff);
        dst[j++] = (byte) ((x >>> 8) & 0xff);
        dst[j++] = (byte) ((x >>> 16) & 0xff);
        dst[j++] = (byte) ((x >>> 24) & 0xff);
    }
    return dst;
}

两者似乎都稍微增加了一点,约占5%.我没有严格测试他们,以确认.

是否有任何技术可以加速这种文件写入操作,还是有关Java IO写入性能最佳实践的相关指南?

解决方法

我看了三个选择:

>使用DataOutputStream;
>使用ObjectOutputStream(对于Serializable对象,int []是);和
>使用FileChannel.

结果是

DataOutputStream wrote 1,000,000 ints in 3,159.716 ms
ObjectOutputStream wrote 1,000 ints in 295.602 ms
FileChannel wrote 1,000 ints in 110.094 ms

所以NIO版本是最快的.它还具有允许编辑的优点,这意味着您可以轻松地更改一个int,而ObjectOutputStream将需要读取整个数组,修改它并将其写入文件.

代码如下:

private static final int NUM_INTS = 1000000;

interface IntWriter {
  void write(int[] ints);
}

public static void main(String[] args) {
  int[] ints = new int[NUM_INTS];
  Random r = new Random();
  for (int i=0; i<NUM_INTS; i++) {
    ints[i] = r.nextInt();
  }
  time("DataOutputStream",new IntWriter() {
    public void write(int[] ints) {
      storeDO(ints);
    }
  },ints);
  time("ObjectOutputStream",new IntWriter() {
    public void write(int[] ints) {
      storeOO(ints);
    }
  },ints);
  time("FileChannel",new IntWriter() {
    public void write(int[] ints) {
      storeFC(ints);
    }
  },ints);
}

private static void time(String name,IntWriter writer,int[] ints) {
  long start = System.nanoTime();
  writer.write(ints);
  long end = System.nanoTime();
  double ms = (end - start) / 1000000d;
  System.out.printf("%s wrote %,d ints in %,.3f ms%n",name,ints.length,ms);
}

private static void storeOO(int[] ints) {
  ObjectOutputStream out = null;
  try {
    out = new ObjectOutputStream(new FileOutputStream("object.out"));
    out.writeObject(ints);
  } catch (IOException e) {
    throw new RuntimeException(e);
  } finally {
    safeClose(out);
  }
}

private static void storeDO(int[] ints) {
  DataOutputStream out = null;
  try {
    out = new DataOutputStream(new FileOutputStream("data.out"));
    for (int anInt : ints) {
      out.write(anInt);
    }
  } catch (IOException e) {
    throw new RuntimeException(e);
  } finally {
    safeClose(out);
  }
}

private static void storeFC(int[] ints) {
  FileOutputStream out = null;
  try {
    out = new FileOutputStream("fc.out");
    FileChannel file = out.getChannel();
    ByteBuffer buf = file.map(FileChannel.MapMode.READ_WRITE,4 * ints.length);
    for (int i : ints) {
      buf.putInt(i);
    }
    file.close();
  } catch (IOException e) {
    throw new RuntimeException(e);
  } finally {
    safeClose(out);
  }
}

private static void safeClose(OutputStream out) {
  try {
    if (out != null) {
      out.close();
    }
  } catch (IOException e) {
    // do nothing
  }
}

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...