crypt of decay - worse is better, или регресс прогресса [entries|archive|friends|userinfo]
ketmar

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

worse is better, или регресс прогресса [Apr. 5th, 2017|06:22 pm]
Previous Entry Add to Memories Tell A Friend Next Entry
вообще, я хотел детально рассказать про дизайн egedit, но передумал. нет там ничего, о чём стоило бы детально рассказывать. а недетально сейчас напишу.

1. текст хранится в тупом массиве байтов. для редактирования используется gap buffer.
2. для подсветки массив байтов сопровождается теневым массивом ushort'ов. то есть, каждый байт имеет теневой ushort. сам редактор с ними не делает ничего.
3. редактор делает кэш, в котором указывает позицию начала каждой строки. при добавлении/удалении текста счётчик общего количества строк правится на основе количества добавленых/удалённых '\n'. при изменении строки n кэш для неё и всех последующих строк инвалидатится, а при запросе «хочу позицию строки с номером хер» тупо обновляется до строки «хер» (если надо). преобразование из позиции в номер строки — то же самое, только кэш обновляется до тех пор, пока не дорастёт до нужной позиции. поиск '\n' — тупой memchr. вся эта механика работает на удивление быстро, и преобразования позиция-в-номер-строки — O(log n), потому что двоичный поиск.

собственно, всё: это весь редактор. в таком виде он вполне справляется с файлами на 210 мегабайт, например. читает мгновенно, навигация мгновенная, поиск-и-замена по регулярке — примерно три-четыре секунды на 98000 замен. меня устраивает.

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

мда. чего-то вышло детальней, чем думалось.


теперь к заголовку поста. у меня есть движок на piece chains, где для преобразований position-в-chain используется немного модифицированное red-black tree. чисто теоретически этот движок лучше. линейное сканирование чуть медленней, если кусков много (но не так уж и), зато блягодаря тому, что все структуры можно сделать immutable — совершенно халявное undo. в принципе, в дерево можно вмонтировать не только информацию о позициях, но и счётчик строк, так что оно ещё и автоматически будет поддерживать поиск строки по позиции и наоборот, тоже за O(log n). в целом будет быстрее gap buffer (egedit при вставке первого символа в 210мб ощутимо тормозит, пока двигает дырку в начало файла).

я вполне серьёзно планировал всё переделать на этот движок. потому что из-за бага egedit при каждом удалении двигал дырку в конец файла, а потом на нужное место, и это дико тормозило (всё те же 210мб с поиском-и-заменой не справились и за несколько минут). однако баг починился, и переделывать я передумал. потому что хуле, мощностей много, скорость удовлетворительная — нафига?

вот это и есть регресс прогресса: с увеличением тупой мощности красивые алгоритмы заменяются на тупые. потому что работает же, хуле. с одной стороны — мне это нравится, потому что проще писать и отлаживать. а с другой — немного грустно: меньше мест чтобы выебнуться. ну, я бы первый спросил: «а нахера ты ебался с деревьями, если gap buffer на практике не хуже, зато сильно проще?»


извините, пожалуйста, за ошибки. перечитывать никаких сил нет пока.
Linkmeow!

Comments:
From:(Anonymous)
Date:April 16th, 2017 - 12:17 am
(Link)
А не думал текст тупо в виде массива строк хранить? 99.99% редактируемых файлов состоит из большого количества коротких строчек, а на остальные 0.01% поебать вообще, потому что это либо какая-нибудь бинарщина, либо ещё что, не требующее редактирования. В конце концов, если совсем припечет, всегда можно открыть другой редактор.
[User Picture]
From:[info]ketmar
Date:April 16th, 2017 - 01:15 am
(Link)
можно тогда вообще все пункты пропустить, и сразу перейти к «открыть другой редактор». потому что зачем стараться, писать заточеный под себя редактор, чтобы в итоге всё равно ебаться с другими?

алсо, за хранение текста как массива строк надо убивать, потому что их ресайз режет память на фрагменты. а для начальной загрузки файла требуется или как минимум textsize*2 памяти, или ебаться с буферизированым чтением — чтобы распарзить файл на строки. делать undo тоже менее удобно.

попробуй сам написать массив строк, а потом gap buffer, и ты удивишься: gap buffer, даже с теневыми кэшами — будет проще в реализации. и эффективней.

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

реально, лучше gap buffer — по соотношению простоты реализации и удобных фич — для редакторов текста пока что ничего не придумали. как только память перестала быть ограничивающим фактором — gap buffer начал заруливать всех остальных.

а вот уже для word processor типа abiword я бы взял piece chain, аугментированый какими-нибудь деревьями для быстрого поиска позиций и строк (b-tree, например).

за счёт теневого кэша со смещениями строк, кстати, элементарно реализуются даже достаточно продвинутые штуки типа visual word wrapping и text folding (который ненужен).

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

в апдейтнутой версии движка я вообще забил на обновление кэша смещений по запросу: просто тупо чиню его полностью при каждом изменении текста. для тех же 210 мегов починка занимает около пяти миллисекунд. опять тупая скорость железа победила красивые алгоритмы.
From:(Anonymous)
Date:April 19th, 2017 - 06:31 am
(Link)
потому что их ресайз режет память на фрагменты

Да ладно, беспокоиться о фрагментации памяти? Несуществующая проблема.

а для начальной загрузки файла требуется или как минимум textsize*2 памяти

Зачем? Когда будем изменять строку - тогда и расширим буфер.
Вообще-то, даже если сделать строки немутабельными и тупо пересоздавать их при каждом новом изменении - не будет заметно НИКАКОЙ потери производительности. Любой хуевый пека умеет экран пикселями заполнять в реальном времени есличо - даже очень длинная строчка это вообще ничто по сравнению с графикой, ноль, пикосекунда.
[User Picture]
From:[info]ketmar
Date:April 19th, 2017 - 06:39 am
(Link)
>Несуществующая проблема.
в следующий раз, когда будешь удивляться, почему какая-то софтина такое жирное тормозное говно, выжирающее всю память — посмотри в зеркало. увидишь там ответ.

>Зачем?
а также когда будешь удивляться, почему что-то делает глючную херню. ответ там же. я даже написал, зачем — но ты не просто подумать поленился, ты и читать-то не стал.

если тебе несложно, исполни, пожалуйста, одну мою маленькую просьбу: никогда не пиши программ. я буду ОЧЕНЬ благодарен. пожалуйста.
From:(Anonymous)
Date:April 19th, 2017 - 06:48 am
(Link)
в следующий раз, когда будешь удивляться, почему какая-то софтина такое жирное тормозное говно, выжирающее всю память — посмотри в зеркало. увидишь там ответ.

Хочешь сказать, что софт становится жирным тормозным говном именно из-за фрагментации памяти? Ок.
[User Picture]
From:[info]ketmar
Date:April 19th, 2017 - 06:51 am
(Link)
вот именно поэтому — не пиши. не надо. ты в принципе не понимаешь, как это делать.
From:(Anonymous)
Date:April 19th, 2017 - 07:09 am
(Link)
Зато ты понимаешь, поэтому твоим охуенным софтом пользуются дохуя людей по всему миру, включая других охуенных программистов. (на самом деле нет по всем пунктам лол)
[User Picture]
From:[info]ketmar
Date:April 19th, 2017 - 07:12 am
(Link)
спасибо, продолжай, пожалуйста. ты великолепен в своём полном непонимании, практически идеален.
From:(Anonymous)
Date:April 19th, 2017 - 07:13 am
(Link)
Ты не понимаешь, что такое bottleneck и на какие места нужно забивать хуй в пользу действительно важных оптимизаций. Твой охуенный редактор тратит N циклов на всякие внутренние операции со строчками, а потом в дело вступает шревтовый движок и тратит N * 10000000, чтобы вывести это на экран. Удачных микрооптимизаций, юный падаван.
[User Picture]
From:[info]ketmar
Date:April 19th, 2017 - 07:15 am
(Link)
ёбта, говорящий помидор!!!
From:(Anonymous)
Date:April 19th, 2017 - 07:21 am
(Link)
Дрочи, дрочи. Всё-таки замерь на досуге, сколько времени твой говноэмулятор терминала экрано обновляет по сравнению со всем остальным.
[User Picture]
From:[info]ketmar
Date:April 19th, 2017 - 07:23 am
(Link)
ёбта, дважды говорящий помидор!!!