UNIX sort
명령은 다음과 같이 매우 큰 파일을 정렬 할 수 있습니다.UNIX sort 명령으로 매우 큰 파일을 어떻게 정렬 할 수 있습니까?
sort large_file
정렬 알고리즘은 어떻게 구현됩니까?
메모리를 과도하게 소비하지 않는 이유는 무엇입니까?
UNIX sort
명령은 다음과 같이 매우 큰 파일을 정렬 할 수 있습니다.UNIX sort 명령으로 매우 큰 파일을 어떻게 정렬 할 수 있습니까?
sort large_file
정렬 알고리즘은 어떻게 구현됩니까?
메모리를 과도하게 소비하지 않는 이유는 무엇입니까?
Algorithmic details of UNIX Sort command은 Unix Sort가 외부 R-Way 병합 정렬 알고리즘을 사용한다고 말합니다. 링크는 더 자세한 내용으로 들어가지만 본질적으로 입력을 더 작은 부분 (메모리에 맞춰 짐)으로 나누고 마지막 부분에서 각 부분을 병합합니다.
sort
명령은 작업 데이터를 임시 디스크 파일 (보통 /tmp
)에 저장합니다.
임시 디렉토리 지정을 위해'-T' 사용 –
나는이 프로그램에 익숙하지 않지만 외부 정렬을 통해 이루어 졌다고 생각한다. (문제의 대부분은 임시 파일에 저장되는 반면, 문제의 비교적 작은 부분은 한 번에 메모리에 저장된다.) Donald Knuth의 The Art of Computer Programming, Vol. 3 Sorting and Searching, Section 5.4에서 주제에 대한 자세한 설명을 볼 수 있습니다.
경고 :이 스크립트는 청크 당 하나의 셸을 시작하며, 실제로는 대용량 파일의 경우 수백 개가 될 수 있습니다.
다음은이 목적으로 작성한 스크립트입니다. 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
메모리는 문제가되지 않습니다 - 종류 이미 처리한다. 멀티 코어 CPU를 최적의 상태로 사용하고 싶다면 작은 스크립트 (넷에서 찾을 수있는 것과 비슷하지만 대부분의 경우보다 간단하고 깔끔한)와 같이 구현해야합니다. 조심스럽게 종류의 옵션에서
#!/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*
재미있는 스크립트이지만이 질문에 대답하는 데는 아무런 답변이 없습니다. –
split -b는 바이트 단위로 분할되므로 임의의 위치에서 줄이 잘립니다. – ithkuil
#!/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
봐 성능을 가속화하고 컴퓨터와 문제에 미치는 영향의 이해합니다. 우분투에 주요 매개 변수는 임시 파일의
질문자가 "왜 메모리 사용을 요구하지 않습니다 ? " 그 대답은 역사에서 나왔고 오래된 Unix 시스템은 작았고 기본 메모리 크기는 작게 설정되었습니다. 워크로드가 가능한 한 크게 조정하여 정렬 성능을 크게 향상시킵니다. 작업 디렉토리를 정렬하는 파일의 크기를 최소한 1.25 * 보유 할 수있는 충분한 공간이있는 가장 빠른 장치의 위치로 설정하십시오.
- 80GB의 RAM이있는 상자의 2.5GB 파일에서이 작업을 시도해보십시오. 전체 파일이 그보다 작더라도 실제로는 전체 비율을 사용하고 있습니다. 그게 왜? 심지어 쓸데없는 것으로 보이는 내부 정렬을 사용하지 않더라도 –
아마 sort-S는 파일의 내용을 읽기 전에 정렬 프로세스를위한 메모리를 미리 할당합니다. –
명령을 다시 편집했습니다. UUoC. ;) – ayaz
이것은 흥미 롭습니다. 나는 그것이 어떻게 작동하는지 정말로 모른다. 그러나 나는 추측을 가지고있다. 아마도 각 키의 첫 번째 문자를 이진 트리에 넣을 것이며, 충돌이 발생하면 키의 다음 문자도 사용하므로 필요 이상의 키를 절약하지는 못합니다.그런 다음 각 키를 사용하여 파일에 오프셋을 저장할 수 있으므로 각 줄을 순서대로 찾아서 인쇄 할 수 있습니다. – Zifre
사실, @ayaz는 디스크에 파일이 아니라 파이프에 파일을 정렬하는 것이 더 흥미 롭습니다. 왜냐하면 입력 데이터를 여러 번 통과시킬 수 없다는 것을 분명히 알기 때문입니다. – tvanfosson