|
|
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Привет друзья. Как обычно Илья, Сова, Саша, Чингиз и все остальные. Прошу прощения что отсутстовал почти 3 недели. Были овертаймы и завалы на проекте. Но щас вроде разгреб. В последнее время до меня долетает великий плач и стенания со стороны junior-девелоперов о том что то тут, то там они были завалены на собеседованиях вопросом о сортировке толстых текстовых файлов. Давайте в форуме один раз и навсегда закодим решение и поставим точку в этих трудностях. Буду краток. Надоело растекаться по дереву. Вобщем дано: Input: Код: sql 1. Output: Код: sql 1. Комментарии к ТЗ: 1) Предполагается любая операционная система Windows/Linux/BSD. 2) DBMS не установлен и не используется. 3) Исходный текстовый файл минимум четырёхкратно превышает доступную физическую память. 4) Результатом является - лексикографически отсортированный текстовый файл 5) Кодировки - опциональны. Тоесть мы на них пока забиваем болт. Символы - однобайтные. Приветствуется: 1) C/C++/Rust/D 2) Delphi/FPC 3) Ассемблер. Хардкод и всякие там MMX/SSE1,2,3,4,5/AVX. Что будем обсуждать: 1) Ваши идеи и сорцы. 2) Кардинальность. Структуры данных. Подсчет. Сжатие (возможно?). 3) Дисковая оптимизация. 1,2,3 физических дисковых устройства. Что мы не будем обсуждать. 1) Чужие сорцы. Здесь я поясню что в рамках форума Программирование, лично мне, а также сообществу, интересно говорить с автором и задавать вопросы по исходникам. Поэтому ссылка на github "канает" только в одном случае - если вы автор или участник разработки. 2) Готовые коробочные продукты. Особо также приглашаю в топик Диму-Т т.к. слыхал что у него есть идеи по поводу сортировок. Ау, чел! С уважением, ваш покорный слуга, а также большой ворчун и бухтелка mayton. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 17:10 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
ИМХО тут самое узкое место файловый IO, его и надо оптимизировать. В каком-то топике это уже обсуждали. Читаем сколько влезет в память, сортируем, скидываем во временный файл и так по кругу пока все не прочитаем. Затем слияние временных файлов. У этого метода даже название есть, только не помню, т.к. задача разве что для собеседований, в реальной жизни оптимизация начинается до получения этого биг-файла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 20:01 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Мой поинт в том что при реализации merge-sort мы работаем обычно с 1 дисковым устройством. Допустим это /tmp. Но для эффективного алгоритма слияния нужны минимум 3 дисковых устройства которые работают независимо. Код: sql 1. 2. 3. При таком раскладе в фазе 2 merge-sort мы имеем Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Возможны варианты с компромиссом. Когда у нас (0001) и (0002) читаются с устройства /mnt/disk1, и пишуться в /mnt/disk2 +Надо еще подумать как быть с третьей фазой. По сути решать пасьянс с файловой нагрузкой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 20:11 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Dima TУ этого метода даже название есть, только не помню сортировка слиянием - так и называется . у Кнута хорошо описана ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 20:21 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
ИзопропилDima TУ этого метода даже название есть, только не помню сортировка слиянием - так и называется . у Кнута хорошо описана Не, это другое , тут слияния сразу начинаются, а там слияние уже сортированных массивов. Пофиг как оно называется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 20:33 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonМой поинт в том что при реализации merge-sort мы работаем обычно с 1 дисковым устройством. Допустим это /tmp. Но для эффективного алгоритма слияния нужны минимум 3 дисковых устройства которые работают независимо. Ерунду написал. Нет смысла рассматривать оптимизацию железа для решения данной задачи. Я уже писал "в реальной жизни оптимизация начинается до получения этого биг-файла" Если у тебя эта сортировка происходит регулярно и требует оптимизации, то оптимизацию надо начинать в источнике возникновения файла, т.к. их много, так нагрузку проще распределить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 20:40 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Dima TmaytonМой поинт в том что при реализации merge-sort мы работаем обычно с 1 дисковым устройством. Допустим это /tmp. Но для эффективного алгоритма слияния нужны минимум 3 дисковых устройства которые работают независимо. Ерунду написал. Нет смысла рассматривать оптимизацию железа для решения данной задачи. Я уже писал "в реальной жизни оптимизация начинается до получения этого биг-файла" Если у тебя эта сортировка происходит регулярно и требует оптимизации, то оптимизацию надо начинать в источнике возникновения файла, т.к. их много, так нагрузку проще распределить. ОК. Поговорим тогда про оптимизаци в источнике. Кардинальность. В теории (я не уверен стоит уточнить) это количество уникальных записей. Допустим нам на вход идут данные следующего рода. Код: sql 1. 2. 3. Можно сказать что уникальных записей всего две хотя из текстового файла пришло 3 штуки. Для сортировки и слияния совершенно нет необходимости многократно копировать повторения если на 1-й фазе мы их слегка преобразуем. Мы учтем повторы в виде специального счетчика. Код: sql 1. 2. Счетчик удобно укладывается в алгоритм слияния. Подобно сортировке подсчетом. Его можно тащить аж до последней фазы где два файла сливаются в один равный по размеру исходным данным. По сути это нечто вроде RLE (run-length-encoding). Когда принимать решение о введении счетчика или об отказе от него? Это вопрос. Но в любом случае решение этой задачи потребует хотя-бы одного full-scan текстового файла. И уж коли мы решили это делать то лучше собрать на этом шаге максимум сведений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 21:09 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Dima TЕрунду написал. Нет смысла рассматривать оптимизацию железа для решения данной задачи. Еще дам один комментарий. Речь не идет об оптимизации железа. А скорее о сборе сведений о конфигурации. И если конфигурация позволяет - то почему этим не воспользоваться? Разумеется я не предлагаю форматировать и монтировать диски. Но разве ты, когда экспериментировал с акторами не опрашивал систему на имеющиеся на борту количество CPU-s/Hyper-Threads? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 21:12 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Dima TИМХО тут самое узкое место файловый IO, его и надо оптимизировать. В каком-то топике это уже обсуждали. Читаем сколько влезет в память, сортируем, скидываем во временный файл и так по кругу пока все не прочитаем. Затем слияние временных файлов. У этого метода даже название есть, только не помню, т.к. задача разве что для собеседований, в реальной жизни оптимизация начинается до получения этого биг-файла. Дисковий ввод вывод вторичен. Первичными тормозами будет, как это не странно звучит, кеш файловой системы. Активный ввод вывод будет выганять в своп сортируюшие процессы и тормозить процессы сортировки.. Поэтому первое, о чем должен позаботится программист, открыть все файлы в режиме directio. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 23:33 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Замётано док. Будем форсировать директ. Я уже название придумал. Roilling-triplet algorithm. Типа крутящийся треугольник. А мои сомнения по поводу дискового пасьянса - только что развеялись. Псевдокод. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 23:50 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonМой поинт в том что при реализации merge-sort мы работаем обычно с 1 дисковым устройством. Допустим это /tmp. Но для эффективного алгоритма слияния нужны минимум 3 дисковых устройства которые работают независимо. Код: sql 1. 2. 3. При таком раскладе в фазе 2 merge-sort мы имеем Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Возможны варианты с компромиссом. Когда у нас (0001) и (0002) читаются с устройства /mnt/disk1, и пишуться в /mnt/disk2 +Надо еще подумать как быть с третьей фазой. По сути решать пасьянс с файловой нагрузкой. Так не интересно , с очень высокой вероятность я выиграю имея не лучший алгоритм сортировки ) Я себе могу подключить в полигон для тестов терабайт дискового пространства 50 000 iops и трансфером 2400 МБайт/сек ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2017, 23:52 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
д0kХЯ себе могу подключить в полигон для тестов терабайт дискового пространства 50 000 iops и трансфером 2400 МБайт/сек Да подключай хоть амазон. По сути здесь топик - про собеседование и рассуждения о том как решить данную задачу. Но поскольку я - бухтелка и перфекционист, то я ставлю сверх-задачу, а именно оптимизацию merge-sort при условии что она УЖЕ реализована и корректно работает на 1 локальном дисковом устройстве. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 00:03 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
mayton По сути здесь топик - про собеседование и рассуждения о том как решить данную задачу. ...... а именно оптимизацию merge-sort при условии что она УЖЕ реализована и корректно работает на 1 локальном дисковом устройстве. я не понимаю такую задачу. Если реализована , давай посмотрим код, будем сомтреть как ее улучшать по оптимизации ввода вывода. или мы сначала делаем свою реализацию адаптированную под 1 дисковое устройство ? мне кажется задачу нужно формулировать так. Соровка текстового файлф размером 4 RAM используя минимальное количество операций дискового ввода вывода. ИМХО это задача не сколько для программистов , а больше для математиков. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 01:17 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Я думаю что лучше все таки такая форма Соровка текстового файла размером 4 RAM за минимальное время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 01:26 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonЯ думаю что лучше все таки такая форма Соровка текстового файла размером 4 RAM за минимальное время. Для минимизации времени нужно выравнять условия . 1. Либо должна быть группа эталонных файлов. 2 Либо в алгоритме обязательно должны присутсовать счетчики сравнений, объема и количества пермещений в памяти и дисковых операций. Которые потом будут сравниваться. а скорость должна меряться в попугаях телодвижений системы . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 01:39 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
С эталонными файлами - проблема. Пожалуй это главный косяк этой задачи на собесе. Мы о них ничего не знаем. Это может быть текстовый файл. CSV-экспорт из БД. HTML. И вообще все что угодно. В некоторых постановках максимальная длина строки ограничивалась в 255 символов. В некоторых в 2Г. О кардинальности также нет сведений. Вобщем вот такие вот условия. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 02:12 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Кстате еще не маловажный критерий - длина строки. Я чесно сказать изначально подумал что речь идет о сортировке произвольного текстового файла по словам, а не строкам. Если длина строк одинакова ( в идеале) или разумно детерминирована то скорость можно будет увеличить в несколько разза счет следующего алгоритма. 1. разбиваем файл на блоки. 2. Блок в памяти содержит строки из файла метаструктуру - массив ячеек локации строк struct str_lctn { int block_num; // номер блока загружаемого в память int offset; // смещение строки в файле ( в памяти вычисляется через размер и номер блока ) int size; // размер строки ( опционально ) }; 3 В памяти всегда лежат дискрипторы блоков str_lctn min_lctn ; // локация минимальной строки блока str_lctn max_lctn; // лолкация максимальной строки блока На основании этой информации принимается решение какой блок с каким мержить. 4. сортировка в памяти сводится к сортировке массива str_box. 5. В темповый файл пишутся массивы str_box-ов. 6 . если строки в файле одинаковой длины , то запись финального отсортированного файла производится блоками строк по новому смещению. И вобще без создания нового сортированного файла , а заменой строк местами в имеющемся файле. Не идеально, если не обнаружится критических подводных камней то этот алгоритм - заявка на победу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 02:27 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
д0kХ, я не совсем понял, по какому принципу мы будем бить файл на блоки. (Сорян у меня c блоком - ассоциации c 8K Oracle db_block). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 11:29 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonд0kХ, я не совсем понял, по какому принципу мы будем бить файл на блоки. (Сорян у меня c блоком - ассоциации c 8K Oracle db_block). Импирически подбирать под число ядер, объем памяти, темпака и струкруру файла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 11:53 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Будет сложно просить пользователя вводить эти цифры. Часть из них лучше получить из API по аналогии с lscpu, free, df. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 12:08 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Слияние двух сортированных последовательностей делается в один проход, и памяти не требует. Просто читаем последовательно два источника и пишем в приемник. пример Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Т.е. для оптимизации количества слияний надо разбить исходный на примерно одинаковые блоки и предварительно их сортировать. Про файловый IO я вчера немного не то ляпнул, он важен для слияний, т.к. тут сплошной IO. Если файл не сортированный, то сортировка блоков значительно перекроет время на файловый IO. Как уже писал 20167525 сортировка сортированного не быстрое дело. Т.е. если считаем что файл не сортированный, то одно ядро отдаем под слияния, а все остальные под сортировку блоков. Размер блока надо исходя из количества ядер выбирать, думаю чтобы 4-8 блоков на ядро получалось, чтобы слияния как можно раньше начались. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 12:54 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
Dima TТ.е. если считаем что файл не сортированный, то одно ядро отдаем под слияния, а все остальные под сортировку блоков. Размер блока надо исходя из количества ядер выбирать, думаю чтобы 4-8 блоков на ядро получалось, чтобы слияния как можно раньше начались. Я не просто так делаю акценты на дисковой подсистеме. Если в 1-й фазе для тебя важна скорость сортировки блока в оперативке (можно поискать мультипоточный хоар) То в фазе №2 у нас будет суровое физическое ограничение. Вы хоть в 16 ядер запускайте merge двух блоков (файлов) но события ожидания у вас выстроятся в очередь на канале вашего жесткого диска. Фактически фаза 2 представляет из себя сплошное дисковое копирование. И если кто-то из вас часто и много копировал большие файлы (бэкапы) а я - много копировал, то вы представляете себе масштаб трагедии. Если у вас не RAID стойка - а обычная рабочая станция то никакого масштабирования не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 13:01 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonDima TТ.е. если считаем что файл не сортированный, то одно ядро отдаем под слияния, а все остальные под сортировку блоков. Размер блока надо исходя из количества ядер выбирать, думаю чтобы 4-8 блоков на ядро получалось, чтобы слияния как можно раньше начались. Я не просто так делаю акценты на дисковой подсистеме. Если в 1-й фазе для тебя важна скорость сортировки блока в оперативке (можно поискать мультипоточный хоар) То в фазе №2 у нас будет суровое физическое ограничение. Вы хоть в 16 ядер запускайте merge двух блоков (файлов) но события ожидания у вас выстроятся в очередь на канале вашего жесткого диска. Фактически фаза 2 представляет из себя сплошное дисковое копирование. И если кто-то из вас часто и много копировал большие файлы (бэкапы) а я - много копировал, то вы представляете себе масштаб трагедии. Если у вас не RAID стойка - а обычная рабочая станция то никакого масштабирования не будет. У меня есть другой более наглядный пример. и кстате о праметрах. Есть одна такая распальцованная СУБД Оракл, ей сколько памяти не давай она за сортировками при постройке индексов в темп залазит раньше. чем другие СУБД с аналогичными объемами на аналогичном железе соотвественно разница в десятки раз быстрее., за счет более оптимального использования доступной оперативной памяти и ядер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 13:31 |
|
||
|
Тяпничная huge-сортировка
|
|||
|---|---|---|---|
|
#18+
maytonБудет сложно просить пользователя вводить эти цифры. Часть из них лучше получить из API по аналогии с lscpu, free, df. С этим нет проблем , есть проблемы со абстрактной структурой файла, и невнятной постановкой задачи. Под которую нужно писать сборщик статистики. То есть как минимум +1 сканирование, и непонятный объем метаданных в оперативной памяти, для создания универсальной серебрянной пули из говна . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.03.2017, 13:37 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39417498&tid=1340453]: |
0ms |
get settings: |
7ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
214ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 230ms |
| total: | 549ms |

| 0 / 0 |
