Команда UNIX sortможе сортувати дуже великий файл на зразок цього:
sort large_file
Як реалізується алгоритм сортування?
Чому це не викликає надмірного споживання пам’яті?
Команда UNIX sortможе сортувати дуже великий файл на зразок цього:
sort large_file
Як реалізується алгоритм сортування?
Чому це не викликає надмірного споживання пам’яті?
Відповіді:
У алгоритмічні деталі команди UNIX Сортування говорить Unix Сортування використовує алгоритм в злиття зовнішнього R-Way сортування. Посилання йде на більш детальну інформацію, але, по суті, вона ділить вхід на менші частини (які вписуються в пам'ять), а потім об'єднує кожну частину разом у кінці.
У sortкоманді зберігає робочі дані в тимчасових файлах диск (зазвичай /tmp).
-Tщоб вказати temp dir
УВАГА: Цей сценарій запускає одну оболонку на шматок, для дійсно великих файлів це може бути сотні.
Ось сценарій, який я написав для цього. На 4 процесорній машині це покращило продуктивність сортування на 100%!
#! /bin/ksh
MAX_LINES_PER_CHUNK=1000000
ORIGINAL_FILE=$1
SORTED_FILE=$2
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split.
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted
usage ()
{
echo Parallel sort
echo usage: psort file1 file2
echo Sorts text file file1 and stores the output in file2
echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines
echo and each chunk will be sorted in parallel
}
# test if we have two arguments on the command line
if [ $# != 2 ]
then
usage
exit
fi
#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
rm -f $SORTED_FILE
#Splitting $ORIGINAL_FILE into chunks ...
split -l $MAX_LINES_PER_CHUNK $ORIGINAL_FILE $CHUNK_FILE_PREFIX
for file in $CHUNK_FILE_PREFIX*
do
sort $file > $file.sorted &
done
wait
#Merging chunks to $SORTED_FILE ...
sort -m $SORTED_CHUNK_FILES > $SORTED_FILE
#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
Дивіться також: " Сортування великих файлів швидше за допомогою сценарію оболонки "
Я не знайомий з програмою, але я думаю, що це робиться за допомогою зовнішнього сортування (більша частина проблеми зберігається у тимчасових файлах, тоді як відносно невелика частина проблеми зберігається в пам'яті за раз). Див. Дональд Кнут " Мистецтво комп'ютерного програмування", т. 3 Сортування та пошук, Розділ 5.4 для дуже поглибленого обговорення теми.
#!/bin/bash
usage ()
{
echo Parallel sort
echo usage: psort file1 file2
echo Sorts text file file1 and stores the output in file2
}
# test if we have two arguments on the command line
if [ $# != 2 ]
then
usage
exit
fi
pv $1 | parallel --pipe --files sort -S512M | parallel -Xj1 sort -S1024M -m {} ';' rm {} > $2
Погляньте уважно на варіанти сортування, щоб підвищити швидкість роботи та зрозуміти, що це впливає на вашу машину та проблеми. Основними параметрами Ubuntu є
Запитуючий запитує: "Чому немає високого використання пам'яті?" Відповідь на це приходить з історії, старі машини Unix були невеликими, а розмір пам'яті за замовчуванням встановлено невеликим. Налаштуйте це якомога більше, щоб ваші навантаження були значно поліпшені. Встановіть робочий каталог на місце на вашому найшвидшому пристрої, в якому є достатньо місця для розміщення принаймні 1,25 * розміру файлу, який сортується.
Пам'ять не повинна бути проблемою - сортування вже це бере на себе. Якщо ви хочете оптимально використовувати ваш багатоядерний процесор, я реалізую це в невеликому сценарії (подібний до деяких, який ви можете знайти в мережі, але простіший / чистіший, ніж більшість із них;)).
#!/bin/bash
# Usage: psort filename <chunksize> <threads>
# In this example a the file largefile is split into chunks of 20 MB.
# The part are sorted in 4 simultaneous threads before getting merged.
#
# psort largefile.txt 20m 4
#
# by h.p.
split -b $2 $1 $1.part
suffix=sorttemp.`date +%s`
nthreads=$3
i=0
for fname in `ls *$1.part*`
do
let i++
sort $fname > $fname.$suffix &
mres=$(($i % $nthreads))
test "$mres" -eq 0 && wait
done
wait
sort -m *.$suffix
rm $1.part*