Найшвидший спосіб видалити дублікати з великого списку слів?


14

Мені потрібно присвятити великий список слів. Я спробував кілька команд і зробив кілька досліджень тут і тут, де вони пояснюють, що, як видається, найшвидшим способом подвоєння списку слів є використання awk.

awk -> O (n)? сортувати -> O (n журнал n)?

Однак я виявив, що це здається неправдою. Ось мої результати тестування:

sort -u input.txt -o output.txt 

реальний
користувач 0m12.446s 0m11.347s
sys 0m0.906s

awk '!x[$0]++' input.txt > output.txt

реальний
користувач 0m47.221s 0m45.419s
sys 0m1.260s

Тож використання сорту -у в 3,7 рази швидше. Чому це? чи існує ще швидший метод зробити дедуплікацію?

*********** Оновлення ********

Як хтось зазначав у коментарях, можливо, мій список слів вже певною мірою був відсортований. Щоб виключити цю можливість, я створив два списки слів за допомогою цього сценарію python .

Список1 = 7 Мб
Список2 = 690 Мб

Результати AWK:
Список1
реальний 0m1.643s
користувач 0m1.565s
sys 0m0.062s

Список2
реальний
користувач 2m6.918s 2m4.499s
sys 0m1.345s

Результати SORT:
Список1
реальний
користувач 0m0.724s 0m0.666s
sys 0m0.048s

Список2
реальний
користувач 1m27.254s 1m25.013s
sys 0m1.251s


Чи може бути, що ваші вхідні дані вже відсортовані?
iruvar

Я буду генерувати випадковий список з цифрами і перевіряти, щоб переконатися
karlpy

2
Позначення Big O - це те, що відбувається, коли довжина введення наближається до нескінченності: це повідомляє вам алгоритм масштабування з великим входом. Деякі алгоритми краще працюють при невеликих розмірах вводу.
ctrl-alt-delor

1
Карлпі, яке замовлення ти виконав, пробудився першим чи сортував? Це може
змінитися

1
@karlpy: "Я змінив ім'я файлу ..." Якщо ви маєте на увазі, що ви перейменували файл, це недостатньо добре. Перейменування файлу просто пов'язує нове ім'я зі старим inode, який все ще вказує на ті самі старі блоки даних. Якщо вони були кешовані, вони все ще кешуються. ISTM, що набагато кращою технікою було б (1) зробити копію файлу, а потім (2) виконати одну команду на одному файлі та (3) виконати іншу команду на іншому.
Скотт

Відповіді:


3

Ви ставите неправильне запитання, або ставите запитання неправильно та в неправильному стеці, це краще питання, яке потрібно задати в програмуванні / стеку-переповненні для людей, щоб дати вам відповіді на основі алгоритмів, які використовуються всередині awk та сортування.

PS: також виконайте необхідні за допомогою nawk, mawk та gawk, щоб дати нам більше деталей для "зони в";) та виконайте пробіжки, як у 100 разів кожен з мінімумом, max, середньою та стандартним відхиленням.

Будь-який випадок повертається до питання, що знаходиться в CompSci 210, йдеться про використовувані алгоритми. Сортування використовує декілька, залежно від розмірів та обмежень пам'яті, на які потрапило, щоб зберегти файли на диск у тимчасових файлах для об'єднання, відсортованих після закінчення пам’яті, і вам доведеться переглянути вихідний код, щоб побачити, що спеціальна команда sort (1) використовує в конкретній ОС, на якій ви працюєте, але з досвіду завантажується в пам'ять наскільки це можливо, зробіть швидкий сортування на ній, випишіть на диск, повторіть промивання та на в кінці він зробить тип злиття невеликих відсортованих файлів. Отже, тут ви будете мати O (n * log2 (N)) для деталей, а потім приблизну операцію злиття O (n * log (n))

awk: Механізм x [$ 0] ++ "припустимо" використовувати хешування. АЛЕ проблема з хешуванням, передбачувана операція "пошуку" O (1), - це зіткнення та керування зіткненнями. Це може спричинити проблему, коли дані не дуже добре поширюються, не заповнюються відра тощо. У великих списках хешування може бути великою проблемою з пам'яттю, якщо керування зіткненнями не буде виконано правильно (і вам може знадобитися налаштуйте алгоритми хешування для очікуваних даних), а потім вам потрібно переглянути ефективність фактичних функцій хешування, і тоді O (1) може бути ближче до O (log (n)) для вставок (тобто. O (1) для першого пошуку, і якщо його НЕ існує, ви додасте його, яке може бути O (log (n))), і що тоді n * O (1) стає * O (log (n)) = > O (n * log (n)), не кажучи вже про те, що ви також робите речі "інтерпретовано" :)


-2

Різниця в швидкості полягає в тому, що 'sort' - це команда ( посилання ), тоді як 'awk' - мова програмування ( посилання ).

Команда 'сортування' приймає введення та повернення виводу. Тоді як 'awk' - мова програмування, яка спочатку інтерпретує код (команда термінала), а потім починає обробку на ньому. Просто як це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.