Вопрос проверяет понимание алгоритмов внешней сортировки и умение работать с данными, превышающими объём оперативной памяти, что критично для обработки больших логов, дампов баз данных или аналитических данных.
Когда файл слишком велик для загрузки в оперативную память целиком, стандартные алгоритмы сортировки (например, быстрая сортировка) неприменимы. Решением является использование алгоритмов внешней сортировки, которые активно работают с диском, организуя данные так, чтобы итоговый файл был отсортирован.
Классический подход — адаптация сортировки слиянием для работы с внешней памятью. Процесс состоит из двух основных фаз.
Ниже приведён схематичный код, иллюстрирующий первую фазу и идею слияния. В реальности нужно управлять буферами ввода/вывода для эффективности.
import heapq
import os
import tempfile
def external_sort(input_filename, output_filename, chunk_size=1000):
"""Упрощённая внешняя сортировка чисел."""
# Фаза 1: Создание отсортированных чанков
temp_files = []
with open(input_filename, 'r') as infile:
chunk = []
while True:
line = infile.readline()
if not line:
break
chunk.append(int(line.strip()))
if len(chunk) >= chunk_size:
chunk.sort()
temp_file = tempfile.NamedTemporaryFile(mode='w+', delete=False)
temp_file.writelines(f"{num}\n" for num in chunk)
temp_file.close()
temp_files.append(temp_file.name)
chunk = []
# Остаток
if chunk:
chunk.sort()
temp_file = tempfile.NamedTemporaryFile(mode='w+', delete=False)
temp_file.writelines(f"{num}\n" for num in chunk)
temp_file.close()
temp_files.append(temp_file.name)
# Фаза 2: k-путевое слияние (здесь k = len(temp_files))
# Открываем все временные файлы для чтения
files = [open(fname, 'r') for fname in temp_files]
# Создаём кучу из первых чисел каждого файла
heap = []
for i, f in enumerate(files):
num = f.readline()
if num:
heapq.heappush(heap, (int(num.strip()), i))
with open(output_filename, 'w') as outfile:
while heap:
val, file_idx = heapq.heappop(heap)
outfile.write(f"{val}\n")
# Берём следующее число из того же файла
next_num = files[file_idx].readline()
if next_num:
heapq.heappush(heap, (int(next_num.strip()), file_idx))
# Закрываем и удаляем временные файлы
for f in files:
f.close()
for fname in temp_files:
os.unlink(fname)
# Пример вызова (предполагается, что input.txt содержит по одному числу на строку)
# external_sort('input.txt', 'sorted_output.txt', chunk_size=100000)
Этот пример демонстрирует принцип, но в реальных системах (например, в утилите sort в Unix) используются более сложные оптимизации: буферизация ввода/вывода, учёт доступной памяти, выбор оптимального k, работа с разными типами данных.
ORDER BY с правильными индексами позволяет делегировать сортировку оптимизированному движку базы данных.Вывод: Внешняя сортировка слиянием — фундаментальный метод для обработки данных, не помещающихся в память. Её стоит применять при работе с большими лог-файлами, дампами данных, в ETL-процессах и в любых ситуациях, где требуется упорядочить огромные объёмы информации на диске. Оптимизации алгоритма позволяют эффективно использовать ресурсы диска и памяти.