sort
คำสั่งUNIX สามารถจัดเรียงไฟล์ที่มีขนาดใหญ่มากดังนี้:
sort large_file
อัลกอริทึมการจัดเรียงใช้งานอย่างไร
เหตุใดจึงไม่ทำให้สิ้นเปลืองหน่วยความจำมากเกินไป?
sort
คำสั่งUNIX สามารถจัดเรียงไฟล์ที่มีขนาดใหญ่มากดังนี้:
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
ดูเพิ่มเติม: "การจัดเรียงไฟล์ขนาดใหญ่ได้เร็วขึ้นด้วยเชลล์สคริปต์ "
ฉันไม่คุ้นเคยกับโปรแกรม แต่ฉันคิดว่ามันทำโดยการจัดเรียงภายนอก (ปัญหาส่วนใหญ่เกิดขึ้นในไฟล์ชั่วคราวในขณะที่ปัญหาส่วนเล็ก ๆ จะถูกเก็บไว้ในหน่วยความจำในแต่ละครั้ง) ดูThe Art of Computer Programming ของ Donald Knuth , Vol. 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 คือ
ผู้ถามถามว่า "ทำไมไม่ใช้หน่วยความจำสูง" คำตอบนั้นมาจากประวัติเครื่องยูนิกซ์รุ่นเก่ามีขนาดเล็กและขนาดหน่วยความจำเริ่มต้นถูกตั้งค่าให้เล็ก ปรับสิ่งนี้ให้ใหญ่ที่สุดสำหรับปริมาณงานของคุณเพื่อปรับปรุงประสิทธิภาพการจัดเรียงอย่างมาก ตั้งค่าไดเร็กทอรีการทำงานเป็นตำแหน่งบนอุปกรณ์ที่เร็วที่สุดของคุณซึ่งมีพื้นที่เพียงพอสำหรับจัดเรียงขนาดไฟล์อย่างน้อย 1.25 *
หน่วยความจำไม่ควรมีปัญหา - sort ดูแลอยู่แล้ว หากคุณต้องการใช้ซีพียูแบบมัลติคอร์ให้เกิดประโยชน์สูงสุดฉันได้ใช้สิ่งนี้ในสคริปต์ขนาดเล็ก (คล้ายกับบางตัวที่คุณอาจพบในเน็ต แต่เรียบง่าย / สะอาดกว่าส่วนใหญ่;))
#!/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*