Я реализовал API, который должен сортировать числа внешне (используя пространство на жестком диске), учитывая входной файл в формате байтов с прямым порядком байтов.Я ограничен 100 МБ ОЗУ (флаг -Xmx100m для аргументов ВМ).Однако сортировка целых чисел (1 000 000 000) на миллиард байтов с помощью моей программы занимает приблизительно 30 минут, что слишком долго для использования.Я не из-за того, что моя программа так неэффективна.
Сейчас я разбиваю входной файл на несколько временных файлов, сортирую их с помощью быстрой сортировки, а затем объединяю с использованием минимальной кучи (https://www.geeksforgeeks.org/external-sorting/). Однако,как я уже говорил, на практике это слишком медленно.
MinHeapNode[] arr = new MinHeapNode[numTempFiles];
FileInputStream[] read = new FileInputStream[numTempFiles];
for(int i = 0; i < read.length; i++)
try {
read[i] = new FileInputStream(i + "");
} catch (Exception e) {
e.printStackTrace();
}
for(int i = 0; i < this.numTempFiles; i++) {
arr[i] = new MinHeapNode();
arr[i].i = i;
try {
byte[] bytes = new byte[4];
read[i].read(bytes);
arr[i].element = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getInt();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
MinHeap heap = new MinHeap(arr, numTempFiles);
int count = 0;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outputfile);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
while(count != numTempFiles) {
MinHeapNode root = heap.getMin();
byte[] bytes = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(root.element).array();
try {
fos.write(bytes);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
byte[] bytearr = new byte[4];
read[root.i].read(bytearr);
root.element = ByteBuffer.wrap(bytearr).order(ByteOrder.BIG_ENDIAN).getInt();
} catch(Exception e) {
root.element = Integer.MAX_VALUE;
count++;
}
heap.replaceMin(root);
}
for(int i = 0; i < numTempFiles; i++)
try{ read[i].close(); }
catch(Exception e) { e.printStackTrace(); }
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}```
Here are some runtimes for filesizes:
2 seconds and 231 milliseconds for 1,000,000 bytes
20 seconds and 330 milliseconds for 10,000,000 bytes
4 minutes, 36 seconds, 940 milliseconds for 100,000,000 bytes
35 minutes, 55 seconds, 642 milliseconds for 1,000,000,000 bytes