Какой сегмент моей внешней программы сортировки является неэффективным / узким местом? - PullRequest
0 голосов
/ 13 июня 2019

Я реализовал 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...