crypt of decay - не понимат [entries|archive|friends|userinfo]
ketmar

[ userinfo | ljr userinfo ]
[ archive | journal archive ]

не понимат [Sep. 25th, 2018|11:33 pm]
Previous Entry Add to Memories Tell A Friend Next Entry
шестнадцать лет уже существует TimSort, который и быстрее quick sort'а на частично отсортированых последовательностях, и вдобавок stable — а в стандартные библиотеки (привет, glibc!) до сих пор квик суют. уже одно то, что TS как минимум не хуже квиксорта, да вдобавок stable — повод мгновенно повыкидывать квик отовсюду, откуда можно. но нет, диды порятнки нюхали и нам заповедовали, так что таскайте свои реализации с собой.
Linkmeow!

Comments:
From:(Anonymous)
Date:September 25th, 2018 - 09:17 pm
(Link)
в нём же баг нашли
From:(Anonymous)
Date:September 25th, 2018 - 09:18 pm
(Link)
и вот так и совали в какойто линупс, а потом выкинули и вернули qsort
[User Picture]
From:[info]ketmar
Date:September 25th, 2018 - 10:23 pm
(Link)
о котором ты знаешь… ты знаешь… а вот: о котором ты знаешь нихуя.
From:(Anonymous)
Date:September 25th, 2018 - 11:29 pm
(Link)
так и есть, нихуя не знаю
а доказательство корректности работы тимсорта существует?
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 12:30 am
(Link)
а вот если бы ты удосужился прочитать:
1. описание алгоритма,
2. статью, где была описана ошибка,
то ты бы не задавал глупых вопросов, например.
From:(Anonymous)
Date:September 25th, 2018 - 11:25 pm
(Link)
не в алгоритме же баг а в реализации алгоритма на сраном ведроиде и в сраной жабе
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 12:32 am
(Link)
во всех реализациях, вообще-то, потому что ошибка была как раз в оригинале. из-за мелких различий в реализации версию для бидона и ведроида уронить было нельзя (не хватит вычислительных ресурсов), версию для жабы достаточно тривиально. что, в общем, неважно, потому что тривиально чинится или незначительным увеличением временного буфера, или усилением проверки инварианта. и все уже давно починили.
From:(Anonymous)
Date:September 26th, 2018 - 08:21 am
(Link)
то есть одни пидарасы не могут написать нормальную реализацию, а у других пидарасов от этого бомбит

все скопом нахуй

>все уже давно починили

а также нахуй
(Replies frozen) (Parent) (Thread)
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 12:28 pm
(Link)
и один ты у нас пишешь всегда без ошибок. гений уровня кнута, а может быть даже и выше. ну, неси свой алгоритм, мы охуеем, а тим утрётся.
(Replies frozen) (Parent) (Thread)
From:(Anonymous)
Date:September 27th, 2018 - 10:26 am
(Link)
какая буква в слове "нахуй" непонятна?
(Replies frozen) (Parent) (Thread)
[User Picture]
From:[info]ketmar
Date:September 27th, 2018 - 10:58 am
(Link)
и то правда. иди нахуй, и никогда не возвращайся, уёбок.
(Replies frozen) (Parent)
From:(Anonymous)
Date:September 25th, 2018 - 09:28 pm
(Link)
ничего круче sleep sort не придумали
From:(Anonymous)
Date:September 26th, 2018 - 04:01 am
(Link)
> таскайте свои реализации с собой

C/C++ одной строчкой
хули тебе не нравится?
From:(Anonymous)
Date:September 26th, 2018 - 04:08 am
(Link)
Legacy же
Диды квиксортили и правнуки будут
[User Picture]
From:[info]mattekudasai
Date:September 26th, 2018 - 11:05 am
(Link)
Ну вот не надо.
В JDK, например, mergesort используется, на основе которого сделан timsort. Просто timsort заточен на типа real world задачи, в которых равномерно случайно распледеленные данные - скорее исключение.
[User Picture]
From:[info]mattekudasai
Date:September 26th, 2018 - 11:16 am
(Link)
Бля, начиная с OpenJDK 7 timsort штоле? Пиздец, а народ то и не в курсе.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 12:32 pm
(Link)
тим даже на полностью рандомных данных (ну, насколько их можно получить) показывает вполне годные результаты — лучше glibc-шного квиксорта. это очень странно, кстати: даже heap sort обходит qsort на таких наборах. по-моему, у меня поломаный тест.
[User Picture]
From:[info]mattekudasai
Date:September 26th, 2018 - 06:32 pm
(Link)
Так что с тестами? Люди волнутся же, сколько можно саспенс этот держать?
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 06:34 pm
(Link)
да воьзми любую из реализаций и проверь. мне лень.
[User Picture]
From:[info]mattekudasai
Date:September 27th, 2018 - 07:43 am
(Link)
Хз, на полностью рандомизированных (на каждой итерации) данных квик все таки пизже, как и ожидалось:

# Warmup: 10 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Benchmark mode: Average time, time/op

Benchmark            Mode  Cnt  Score   Error  Units
SortBench.mergeSort  avgt   20  0.436 ? 0.006  ms/op
SortBench.quickSort  avgt   20  0.206 ? 0.003  ms/op

[User Picture]
From:[info]mattekudasai
Date:September 27th, 2018 - 09:06 am
(Link)
Бля, ты же там с хипсортом сравнивал. Плюс я в тесте проебался чучуть. Новые результаты:
Benchmark            Mode  Cnt  Score   Error  Units
SortBench.heapSort   avgt   20  1.503 ? 0.032  ms/op
SortBench.mergeSort  avgt   20  1.175 ? 0.026  ms/op
SortBench.quickSort  avgt   20  0.886 ? 0.010  ms/op


Сортировка написана одним и тем же человеком, соответственно радиус кривизны рук должен быть плюс-минус одинаков.
[User Picture]
From:[info]mattekudasai
Date:September 27th, 2018 - 09:14 am
(Link)
О, а вот кстати jre-шный timsort. Как и было обещано, он не хуже mergesort'а на случайных данных:
SortBench.jreSort    avgt   20  1.048 ? 0.007  ms/op
[User Picture]
From:[info]dolmatt
Date:September 26th, 2018 - 08:33 am
(Link)
А как ты учился языку? По книгам?
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 12:29 pm
(Link)
какому из тех языков, которые я думаю, что знаю?
[User Picture]
From:[info]dolmatt
Date:September 26th, 2018 - 01:33 pm
(Link)
Вопрос был насчет крестов. Но и всё остальное опиши, если не трудно.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 01:40 pm
(Link)
я кресты и не знаю. их вообще мало кто знает. я лично ограничиваюсь подмножеством «си с простыми классами».

а так — паскаль и си по каким-то не самым лучшим книжкам, а потом все языки из этого класса уже несложно подхватить из чтения кода, и иногда частей спеков.

лисп — по книжке про r-list для автокада, и sicp.

forth — по великолепнейшей «starting forth» от лео броуди.

а потом уже по чём попало и как попало. после накопления критической массы базовых знаний оно всё уже выглядит как: «ага. ясно. это XYZ. понимаю. посмотрим, как тут реализовали.»
From:(Anonymous)
Date:September 26th, 2018 - 03:51 pm
(Link)
Потому что worst-case space complexity: O(n).

Quicksort хорош именно тем, что памяти жрет O(log n). Это две разные категории алгоритмов: одни стабильные (как mergesort), другие к памяти нетребовательные (у heapsort, кстати, худшее время лучше, чем у quicksort - но в среднем он медленнее). Для разных, соответственно, задач. Предложение заменить одно другим так же странно, как предложение заменить jpeg на mp3.

Вот придумал бы кто стабильный in-place алгоритм, да с худшим временем O(log n), да еще и с нормальной константой - вот тогда зажили бы. Но не придумывают же ни хуя. Чаи гоняют в своих институах, по конференциям анекдотики-хуетики рассказывают, а мы блядь ебись а алгоритмами сороковых годов. Думают, что если они PhD в Computer Sience, то можно говном на нас срать. Нейронные блядь сети вместо нормальных алгоритмов выдумывают, а как пахать - так мы. А я на фортране прграммировал, и я не позволю над собой так издеваться. Квантовые алгоритмы, а я их гадов ебал.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 04:06 pm
(Link)
да ладно, тимсорт требует где-то чуть больше килобайта дополнительной памяти под стек этих… как их… runs. совершенно не то, на что стоит обращать внимание во всяких там libc. а если начать улучшать квиксорт на предмет толерантности к «плохим данным», то он тоже начинает или памяти требовать, или замедляется «в общем случае». с тимсортом получаем не медленней, зато мегавин на partially sorted, да ещё и stable. не вижу никакой причины не заменить реализацию qsort на тим.

и да: даже усложнённые варианты квиксорта намного проще в реализации, чем тим. поэтому кому реально надо квик — это пол-экрана кода. а тим заебёшься писать и отлаживать. поэтому я считаю, что в библиотеку — тим. а квик пусть носит кому надо.
From:(Anonymous)
Date:September 26th, 2018 - 04:46 pm
(Link)
Стек, если я правильно понимаю, там нужен только на три run'а - перед тем, как сунуть туда следующий, какие-то два объединяются. Это, действительно, байты.

А вот для того, чтобы смержить два массива, может понадобиться дополнительная память размером с один из них. И если так сложится, что на последнем этапе будет два run'а по гигабайту каждый - то придется где-то брать гигабайт дополнительной памяти.

Частично упорядоченные массивы - это какой-то фантастический случай, честно говоря. Я только один реальный сценарий этого вижу: нам надо поддерживать отсортированный массив каких-то величин, а эти величины продолжают откуда-то поступать. Мы дописываем вновь полученные данные в конец массива, и запускаем тимсорт. Вот тогда заебись будет, любой другой алгоритм соснет.

Только вот умный человек так делать не будет, он отсортирует новые данные (не важно, чем - их все равно мало), а затем смержит два отсортированных массива (причем поскольку в первом массиве уже должно быть место под дополнительные элементы, то нам даже память выделять как бы и не понадобится).

Так что на мой вкус тимсорт - это что-то для питонобыла ебаного, которое сортирует одно и то же по пятьсот раз подряд, потому что не понимают вообще нихуя, Кнута не читали, пидоры сраные, а лезут программировать. Дай им квиксорт - они и его поломают, и хуй себе изрежут.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 05:08 pm
(Link)
>А вот для того, чтобы смержить два массива, может понадобиться дополнительная
>память размером с один из них

ну, там размеры run-ов ограничены (макс. 64, вроде бы), так что если не сортировать массивы, где элементы размерами в мегабайты, то тоже слёзки. алсо, по-моему, есть вариант почти-in-place mergesort. который, конечно, медленней, но если у тебя огромного размера элементы — то вполне вариант переключиться на него. как раз в духе адаптивности тимсорта будет.

>Частично упорядоченные массивы - это какой-то фантастический случай, честно
>говоря

да влёт. в спелунке, например, каждый спрайт имеет depth, по которой спрайты и сортируются перед рендером. и большинство спрайтов вообще одинаковый depth имеют, а у остальных часто встречается ситуация упорядоченности, когда несколько объектов друг на дружке. реально, быстрее их сложить в массив и потом отсортировать, чем двигать куски массива туда-сюда, вставляя в нужное место.

и подобные ситуации встречаются нередко. ирл большинство «рандомных» данных имеют достаточно большие отсортированые куски (потому что данные на самом деле нифига не рандомные жы).

в итоге тимсорт немного жертвует памятью (но нефатально, особенно на современной технике), зато амортизирует весьма часто встречающиеся ирл случаи. плюс — я таки могу и не думать ни о том, что у меня есть вариант, когда программа ВНИЗАПНА просядет нафиг, и делать сортировки по нескольким ключам в несколько же проходов без боязни всё поломать (stable жы). второе не так глупо, как кажется: весьма полезно в UI, где данные можно сортировать/фильтровать по нескольким разным критериям.
From:(Anonymous)
Date:September 26th, 2018 - 05:53 pm
(Link)
Не-не-не, размеры run'ов ограничены СНИЗУ - куски, меньшие 64 элементов сортируются вставками. А сверху предела нет - run'ы объединяются друг с другом, их размер растет. Если все хорошо, то мы все время к большому куску прибавляем маленький (и нам нужна дополнительная память размером с маленький кусок). Но если что-то пойдет не так, то в конце мы будем иметь два здоровых куска в половину массива каждый. То есть обязательно внезапно просядет, хотя и не по времени. В некоторых задачах это не критично (то есть заранее известно, что объем свободной памяти больше сортируемых массивов), но как универсальное решение это не годится.

In-place merge либо не in-place, либо не O(n).

Mergesort ничем не лучше timsort, те же проблемы с памятью, только без плюшек на особых случаях. Собственно, timsort - это и есть mergesort, заоптимизированный под особые случаи.

Что касается примера со спрайтами - Если я правильно понял, там есть статические элементы (более-менее упорядоченные) и динамические, которые из-за своей динамичности не упорядочены? Тогда тоже лучше всю статику упорядочить один раз на всю жизнь, а динамику сортировать отдельно после каждого изменения, затем мержить за O(n).

Ну и вообще - если данные не рандомны, то лучше понять, в чем там закономерность и эксплуатировать ее сознательно. Быстрее будет. А сама идея сделать алгоритм, который с одной стороны универсальный, а с другой - оптимизирован под некие "часто встречающиеся случаи" отдает ебучими нейронными сетями, которые дают правильный ответ, но не всегда, а только с большой вероятностью.

Сортировки в несколько проходов по разным ключам - да, это нормально, особенно если порядок сортировки известен только на рантайме, и захардкодить сравнение по составному ключу нельзя. Но если сортируются сами объекты, а не индексы, то, возможно, лучше иметь очень сложную (и медленную) функцию сравнения, чем двигать объекты по памяти в несколько раз чаще.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 06:18 pm
(Link)
>А сверху предела нет - run'ы объединяются друг с другом, их размер растет.
ок, может быть. я не очень вникал — взял готовое и всё откладываю подробно разобраться.

>In-place merge либо не in-place, либо не O(n).
да, он не совсем O(n). но для огромных кусков вполне есть смысл — там всё равно движение памяти уже слопает порядочно скорости, так что особого смысла пытаться выиграть за счёт strict time нет. мне так кажется.

>Тогда тоже лучше всю статику упорядочить один раз на всю жизнь, а динамику
>сортировать отдельно после каждого изменения, затем мержить за O(n).

там в принципе нет «статики» — там любой объект потенциально динамический. это во-первых. во-вторых, обработка всех объектов одинаковым кодом упрощает этот самый код. в третьих, динамику же всё равно надо в середину статики вставлять: что-то прячется за определённые виды тайлов, что-то нет. в итоге всё равно надо сливать массивы — так зачем изобретать спецалгоритмы (и потом захардкоживать этот отдельный случай в универсальную исполнялку), если можно тупо отсортировать. тут баланс между усложнением кода путём вписывания спецслучаев, и: «да похеру, пусть сортирует, зато код простой как полено.»

изначально в спелунке примерно так и было: несколько гридов даже для разных объектов. а потом я заебался и слил всё в кучу. проебал где-то один процент CPU в итоге, зато выкинул кучу хрупких условий.

опять же, уровень в спелунке разрушаемый и изменяемый, так что проще считать тайлы просто такими же объектами, как и всё остальное.

>если данные не рандомны, то лучше понять, в чем там закономерность и
>эксплуатировать ее сознательно. Быстрее будет.

иногда да. а иногда проще воткнуть алгоритм, который «более-менее справляется» и забить. но беда в том, что в стдлибе такого алгоритма нет — поэтому приходится таскать с собой копипасту.

>А сама идея сделать алгоритм, который с одной стороны универсальный, а с другой -
>оптимизирован под некие "часто встречающиеся случаи" отдает ебучими
>нейронными сетями, которые дают правильный ответ, но не всегда, а только с
>большой вероятностью.

ну да, адаптивные алгоритмы — те ещё банки с червями, конечно. к тому же в них часто эвристики адаптивности взяты или вообще от фонаря, или под технику того времени, когда они создавались, и могут давно уже сосаеть.

я, пожалуй, погорячился с требованием замены. а вот добавить тимсорт в libc, например — это было бы вполне в тему. хоть и раздувание и без того дурных размеров библиотеки, но иметь выбор между «быстрым, но не очень толерантным к сортированым данным» и «не таким быстрым, но хорошо жующим сортированое, да ещё и стабильным» — было бы очень неплохо. хотя бы для того, чтобы люди не таскали с собой разные реализации не самого тривиального алгоритма.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 05:13 pm
(Link)
p.s.: понятно, что описаные в последнем абзаце случаи можно заворкэраундить разными методами, но нафига, если есть сортировщик, который нормально справляется без хаков?
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 04:11 pm
(Link)
p.s.: но если мне надо вдруг зачем-то написать сортировку без стдлиба, то я обычно таки хипсорт сую. потому что «херовые данные» таки встречаются намного чаще, чем кажется, и ну его — пусть лучше в среднем чуть медленней, чем ВНИЗАПНО просядет.
From:(Anonymous)
Date:September 26th, 2018 - 04:52 pm
(Link)
Подход разумного человека, я считаю. Надежность и стабильность важнее скорости, да и не такая там большая разница в средней скорости, что бы было о чем жалеть.
From:(Anonymous)
Date:September 26th, 2018 - 06:04 pm
(Link)
> привет, glibc!

Не знаю, у меня на фряхе в стандартной библиотеке три функции (у них даже man page общая): qsort для рисковых парней, heapsort для тех, кто ценит надежность, и mergesort для тех, кто готов платить памятью за стабильность сортировки. Ничего лишнего, зато есть все необходимое. При этом никто не обещает, что mergesort - это именно mergesort по рецепту фон Наймана. Может быть, в реализации там тот же timsort или еще что-нибудь. И qsort наверняка не совсем qsort.
[User Picture]
From:[info]ketmar
Date:September 26th, 2018 - 06:26 pm
(Link)
разумный подход. я, в общем-то, погорячился с «выкинуть»: «добавить» было бы самое то.

а qsort обычно таки qsort, но с каким-нибудь median (или double median) pivot, чтобы амортизировать плохие случаи.