Добрый день
Как можно сделать сортировку большого числа строк (до 52 миллионов)? . Строки сохранены в тестовые файлы, примерно 1100 файлов (можно сохранить в один фаил, около 15 ГБ), в каждой строке ровно по 900 символов, в строках только символы 0-9, некоторые строки повторяются много раз, а некоторое только один раз. Нужно пройти по всем строкам и подсчитать, какие из них сколько раз повторяются.
Как это сделать не понятно, массивов на 52 млн нет, каждый раз преобходить все файлы очень долго. В процессе можно было бы сохранять каждую строку в виде файла, чтоб повторы отсеивались, но у меня виндовс 10 почему-то не поддерживает длинные имена.
генеришь файл как-то так
base64 /dev/urandom | head -c 4e9 > big.txt
Это задача на external merge sort.
Руками можно написать скрипт:
1. Отсортировать содержимое файлов отдельно по возрастанию. Лучше распараллелить этот шаг.
2. Завести массив курсоров к файлам. Размер массива - кол-во файлов, курсор - номер строки.
3. Выставить все курсоры в 0, т.е. они указывают на первую строку.
4. Теперь пройтись в цикле по всем строкам на которые указывают курсоры и найти наименьшую.
5. Записать эту строчку в итоговый файл или пометить как +1. Курсор сместить на след строчку.
6. Повторять шаги 4-5 пока все курсоры не будут указывать в конец файлов.
Но лучше использовать консольные утилиты если их знаешь. Наверняка они есть, но я, увы, их не знаю.
SELECT line, count(*) FROM lines GROUP BY line ORDER BY line;
igalinov1
Для подсчета количества повторений каждой строки можно использовать хэш-таблицу. Ключом в хэш-таблице может быть сама строка, а значением - количество ее повторений. При проходе по каждой строке файла, мы можем проверять, есть ли она уже в хэш-таблице. Если да, то увеличиваем значение на единицу. Если нет, то добавляем строку в таблицу со значением
Если это не наперегонки, то может попробовать просто взять и отсортировать? У меня нет места на 15 гигабайт, но 7 гигабайт данных ниже сортируются ~8 минут:
cat 7g | sort | uniq -c | sort -rn > xxx
7 гигабайт данных ниже сортируются ~8 минут
И кто считает что современные компы крутые девайсы ?
Ведро с болтами.
Полное разочарование в компьютерах.
entryway ты сам писал тест сортировки семи гиг ? На с++ писал ?
ronniko
> entryway ты сам писал тест сортировки семи гиг ? На с++ писал ?
Нет, просто вызывал стандартные утилиты OS.
> большого числа строк (до 52 миллионов)
большое будет когда миллиарды
а так второй пост
igalinov1
Если только повторы считать, то самое простое - сортировать по какому-то хэшу, разбить на части, уже влезающие в оперативку, а там уж пройтись точным сравнением для повторяющихся значений хэш.
Еще дерево строк можно использовать, вроде может сильно сократить обьем за счет повторяющихся частей.
Или MergeSort (уже предлагали) - читаешь по строке с двух файлов, пишешь в третий (дофига чтений винта и репозицонирований головки).
Извращаться нужно только если в системе не хватает памяти, а так, делаешь несколько массивов и функцию прослойку между ними и счётчиком. Если же памяти не хватает, а тебе нужно убрать все повторы, то разделяешь свои данные на массивы по ~4Гб, обрабатываешь каждый поштучно и пересохраняшь - это первичная обработка. Затем занимаешься вторичной - если не можешь выделить на работу 8Гб, то дробишь свои файлы вдвое, после сравниваешь каждый по очереди с каждым из других и обрабатываешь. На паскале это элементарная задача запрограммировать самому (с гото конечно, потому-что без него - дикий ужас и пляска на граблях), без всяких утилит - пока будешь их изучать, уже свою уже почти допишешь.
MetalHeart
> 2.
> 3.
> 4.
> 5.
> 6.
> Но лучше использовать консольные утилиты если их знаешь.
sort -m
Тема в архиве.