我必须在java中编写一个外部排序程序,它给出一个包含任意数量整数的文件A,只使用文件B(大小相同)对它们进行排序。对于第一阶段,我正在将文件块读入ram,使用内置的java排序并写回文件B,但事实证明这非常慢。我想知道我的代码中是否有任何明显的低效率?请注意,input1和output是RandomAccessFile Objcets,BUFFER_SIZE是在运行时由可用内存量决定的块大小。
public void SortBlocks() throws IOException{
int startTime = (int) System.currentTimeMillis();
input1.seek(0);output.seek(0);
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(input1.getFD()),2048));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(output.getFD()),2048));
int[] buffer = new int[BUFFER_SIZE];
int j=0;
for(int i=0; i<input1.length();i+=4){
buffer[j] = in.readInt();
j++;
if(j == BUFFER_SIZE){
writeInts(buffer,out,j);
j=0;
}
}
writeInts(buffer,out,j);
out.flush();
SwitchIO();
int endTime = (int) System.currentTimeMillis();
System.out.println("sorted blocks in " + Integer.toString(endTime-startTime));
}
private static void writeInts(int[] Ints, DataOutputStream out, int size) throws IOException{
Arrays.sort(Ints,0,size);
for(int i=0;i<size;i++){
out.writeInt(Ints[i]);
}
}
提前感谢您的反馈。
答案 0 :(得分:1)
最明显的低效率是input1.length()
的使用,这是一项相对昂贵的操作,你在每个int
值上调用它。
我不明白为什么在默认(8192)效率更高时减少缓冲区大小。
如果您正在阅读文件,我会使用ByteBuffer作为IntBuffer。瓶颈可能是您读取和写入数据的方式。以原生顺序使用int
值可以提高翻译性能。 (而不是默认哪个大端)
如果您将文件作为内存映射文件访问,则可以正常处理大于内存大小的文件。