Масштабованість 'sort -u' для гігантських файлів


23

Що таке розумна межа масштабування 'sort -u'? (у розмірах "довжина рядка", "кількість рядків", "загальний розмір файлу"?)

Яка альтернатива Unix для файлів, що перевищують це в розмірі "кількість рядків"? (Звичайно, я легко можу реалізувати її, але мені було цікаво, чи є щось, що можна зробити за допомогою декількох стандартних команд Linux?)


Для тих, хто може скористатись двійковим пошуком у ньому чи знати як: unix.stackexchange.com/q/247508/9689
Grzegorz Wierzowiecki

2
Бувають ситуації, коли uniqперед тим, як sort -uдопомогти. До речі, для ASCII дані дуже LC_ALL=C sortшвидко прискорюють GNU sort(див. Цю відповідь )
Walter Tross

Відповіді:


39

Те, sortщо ви знайдете в Linux, походить від пакета coreutils і реалізує зовнішнє злиття R-Way . Він розбиває дані на шматки, якими він може обробляти пам'ять, зберігає їх на диску і потім об'єднує їх. Шматки робляться паралельно, якщо машина має для цього процесори.

Отже, якщо має бути обмеження, це вільний простір на диску, який sortможна використовувати для зберігання тимчасових файлів, які він повинен об'єднати, поєднаних з результатом.


3
Зауважте, що сортування GNU може стискати ці тимчасові файли, щоб ще більше упакувати (і збільшити продуктивність на повільних дисках).
Стефан Шазелас

1
@ StéphaneChazelas Дякую за оновлення. Мені було цікаво, чи сортування було досить розумним для видалення файлів фрагментів, коли один повністю об'єднаний (що може бути легко, якщо джерело вже частково відсортовано) як оптимізація простору. У мене сьогодні немає часу зануритися у вихідний код :-(
Антон,

3
Крім пам'яті, є ще один обмеження, яке стосується фази злиття: кількість файлів, які можна одночасно відкрити. Зазвичай це обмеження, накладене операційною системою. Сортування GNU також справляється з цим, рекурсивно об'єднуючи кількість файлів, які він може відкрити за один раз!
Діомідіс Спінеліс

@ StéphaneChazelas Якби я розробляв інструмент спеціально для сортування дуже великих файлів, я б зберігав рядки як індекс у вихідний файл. Чи робить це GNU сортуванням чи просто використовує звичайний алгоритм стиснення?
Випадково832

3
@ Random832, і це означає, що можна перезаписати файл над собою ( sort -o file file)
Stéphane Chazelas

1

Я не можу говорити про конкретні постачальники реалізації, але UNIX sortреалізація розбиває великі файли на менші файли, сортує ці файли, а потім об'єднує відсортовані менші файли в агрегований відсортований вихід.

Єдиним обмеженням є дисковий простір для менших файлів, створених безпосередньо sort, але файли можуть бути перенаправлені до довільної каталогів, встановивши змінну середовища TMPDIR.


3
Що саме ви називаєте реалізацією сортування UNIX ? Це оригінал з Unix версії 3? Сторінка man каже, що вона не може сортувати файли розміром більше 128 КБ.
Стефан Шазелас

Що ви розумієте під Unix версії 3? Версія з 1973 року? Оригінальна реалізація сортування UNIX була удосконалена з роками та IIRC, версія Solaris навіть набагато швидша, ніж версія GNU. Звичайно, 25 років тому сортування було вдосконалено для розуміння багатобайтових символів, і те, що я пам’ятаю з обговорення USENET, це те, що це було зроблено ефективно на Solaris. BTW: man largefileперераховує sortвеликі файли.
schily

2
Отже, ви насправді говорите про конкретну версію постачальника Oracle sort? Або будь-яка похідна якоїсь версії сорту AT&T Unix? Або будь-яку сертифіковану версію Unix sort(наприклад, GNU sortдля OS / X)?
Стефан Шазелас

Якість сучасних sortреалізацій щодо багатобайтових символів може відрізнятися, той факт, що sortвикористовуються розділені проміжні файли, є загальним для всіх реалізацій UNIX, заснованих на вихідному коді. ДО РЕЧІ: версія Solaris є ОСС як «OpenSolaris», див sourceforge.net/p/schillix-on/schillix-on/ci/default/tree/usr / ...
Шили

25 років тому UTF-8 ще не був винайдений? Підтримка локалів UTF-8 була додана в Solaris 7 ( 1 , 2 ). Ви маєте на увазі якийсь інший багатобайтовий набір символів?
Стефан Шазелас

1

На основі https://blog.mafr.de/2010/05/23/sorting-large-files/ та /unix//a/88704/9689 :

split -n l/20 input input-
for inpf in input-* ; do
    sort --parallel="$(nproc --all)" "${inpf}" > sorted-"{$inpf}"
done
sort -m sorted-input-* > sorted-input

Оновлення:

З відповідей вище , ми бачимо , що sortвже робить те , що згаданий фрагмент коду - тобто зовнішній R-Way злиття . Тож зрештою працює просто:

sort --parallel="$(nproc --all)" -u input > output

Повинно бути достатнім

Мої поточні припущення (без перевірки коду) щодо лімітів:

  • Максимальна довжина рядка обмежена кількістю фізичної пам'яті. Сортувати потрібно, щоб принаймні два розмістилося в пам'яті
  • кількість рядків - я не знаю
  • розмір файлу - звичайно за файловою системою
  • кількість відкритих файлів паралельно - залежно від операційної системи (дякую Diomidis Spinellis за те, що вказав на це!)

(Ця відповідь позначена як вікі спільноти - спонукайте її покращити! :))


2
GNU sortсортує паралельно за замовчуванням (починаючи з 2010 року після цієї сторінки, на яку ви посилаєтесь), --parallelпотрібно зменшити кількість одночасних потоків, а не дозволяти sortвизначати оптимальну. Сортування вже робить розщеплення та злиття внутрішньо більш ефективним способом. Я сумніваюся, що додаткове розщеплення допоможе.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.