Информация об изменениях

Сообщение Re[7]: Как написать редактор текстов на C#? от 02.11.2022 5:20

Изменено 02.11.2022 5:21 Sinclair

Re[7]: Как написать редактор текстов на C#?
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Это значит, что будет массив из пар, например, строк и байтов (или дерево с хештаблицами, чтобы в строках искать быстрее, пока неважно)

Это значит, что у вас даже для маленьких текстов будет +1 уровень косвенности. То есть вместо просто символа A вы храните у себя сам символ А, и ещё массив ссылок на строки, у которых вначале идёт длина, и уже потом — символы UCS4, из которых собственно и состоит текст. Ну либо вы оставляете null для тех символов, которые означают сами себя, тогда немножко экономите по памяти, но производительность всё равно будет так себе.
Весь выигрыш от возможности сделать line[i] вы тут же и потеряете. На первый взгляд кажется, что держать вместо этого дерево строк, в котором каждый лист будет в какой-то одной кодировке, будет гораздо эффективнее.
Чисто Latin1-текст будет ровно одним фрагментом однобайтовых символов.

ЭФ>В тот момент, когда количество символов станет превышать 256 или 65536 (что вряд ли), будет происходить перекодирование всего текста (с копированием по памяти) во внутреннюю кодировку с удвоенным числом битов, но по-прежнему одинаковым на все Grapheme Cluster-ы.

С точки зрения пользователя это будет выглядеть как пауза в работе, и про вас будут писать на хабре "о боже, 2023 год, а у меня ввод текста лагает".
Дерево позволяет все ситуации обработать за O(1).
ЭФ>1) я не собираюсь "разбирать" длинные Grapheme Cluster-ы (они же TextElement в .NET)

ЭФ>редактор не будет уметь их редактировать, только копипастить из буфера целиком (в буфер они будут попадать из браузера) или стирать насмерть.

Тогда придётся их разбирать. Ровно потому, что у вас одна "буква" (то, что стирается целиком при нажатии backspace или del) занимает неизвестное количество "символов", в какой кодировке бы они ни были. Опять же, в дереве вы можете держать такой кластер отдельным листом, и забесплатно иметь возможность быстро перемещаться между "буквами".

ЭФ>2) про границы слов я пока не думал вообще, но такая информация скорее всего получается из CharUnicodeInfo

ЭФ>Если не получится, поищу на гитхабе библиотеку, которая реализует
ЭФ>"Unicode UAX #29 §4.1 default word boundary specification"
Библиотека — это хорошо. Но вопрос в том, как вы будете эти границы искать в момент нажатия Ctrl-влево или Ctrl-вправо. Линейным поиском по символам внутренней кодировки? С учётом того, что для восстановления полноценного UCS4 вам нужно прыгать по двум ссылкам для каждого символа?
Опять же имеет смысл использовать для этого древовидную структуру, в которой всё это делается за O(1).

ЭФ>3) про размер памяти под текст тоже не думал и не буду, у меня на одной из машине 256GB RAM, буду хранить текстовый буфер в памяти на ней.

Если вас не беспокоит размер памяти, тогда нафига задуряться с перекодировками? Сразу храните всё в UCS4.

ЭФ>4) про шрифты я ещё ничего не знаю, буду читать позже. Мне достаточно повторить то, что делает Firefox (потому что я именно из него копирую).
Re[7]: Как написать редактор текстов на C#?
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Это значит, что будет массив из пар, например, строк и байтов (или дерево с хештаблицами, чтобы в строках искать быстрее, пока неважно)

Это значит, что у вас даже для маленьких текстов будет +1 уровень косвенности. То есть вместо просто символа A вы храните у себя сам символ А, и ещё массив ссылок на строки, у которых вначале идёт длина, и уже потом — символы UCS4, из которых собственно и состоит текст. Ну либо вы оставляете null для тех символов, которые означают сами себя, тогда немножко экономите по памяти, но производительность всё равно будет так себе.
Весь выигрыш от возможности сделать line[i] вы тут же и потеряете. К тому же не сможете пользоваться векторными инструкциями для ускорения операций.
На первый взгляд кажется, что держать вместо этого дерево строк, в котором каждый лист будет в какой-то одной кодировке, будет гораздо эффективнее.
Чисто Latin1-текст будет ровно одним фрагментом однобайтовых символов.

ЭФ>В тот момент, когда количество символов станет превышать 256 или 65536 (что вряд ли), будет происходить перекодирование всего текста (с копированием по памяти) во внутреннюю кодировку с удвоенным числом битов, но по-прежнему одинаковым на все Grapheme Cluster-ы.

С точки зрения пользователя это будет выглядеть как пауза в работе, и про вас будут писать на хабре "о боже, 2023 год, а у меня ввод текста лагает".
Дерево позволяет все ситуации обработать за O(1).
ЭФ>1) я не собираюсь "разбирать" длинные Grapheme Cluster-ы (они же TextElement в .NET)

ЭФ>редактор не будет уметь их редактировать, только копипастить из буфера целиком (в буфер они будут попадать из браузера) или стирать насмерть.

Тогда придётся их разбирать. Ровно потому, что у вас одна "буква" (то, что стирается целиком при нажатии backspace или del) занимает неизвестное количество "символов", в какой кодировке бы они ни были. Опять же, в дереве вы можете держать такой кластер отдельным листом, и забесплатно иметь возможность быстро перемещаться между "буквами".

ЭФ>2) про границы слов я пока не думал вообще, но такая информация скорее всего получается из CharUnicodeInfo

ЭФ>Если не получится, поищу на гитхабе библиотеку, которая реализует
ЭФ>"Unicode UAX #29 §4.1 default word boundary specification"
Библиотека — это хорошо. Но вопрос в том, как вы будете эти границы искать в момент нажатия Ctrl-влево или Ctrl-вправо. Линейным поиском по символам внутренней кодировки? С учётом того, что для восстановления полноценного UCS4 вам нужно прыгать по двум ссылкам для каждого символа?
Опять же имеет смысл использовать для этого древовидную структуру, в которой всё это делается за O(1).

ЭФ>3) про размер памяти под текст тоже не думал и не буду, у меня на одной из машине 256GB RAM, буду хранить текстовый буфер в памяти на ней.

Если вас не беспокоит размер памяти, тогда нафига задуряться с перекодировками? Сразу храните всё в UCS4.

ЭФ>4) про шрифты я ещё ничего не знаю, буду читать позже. Мне достаточно повторить то, что делает Firefox (потому что я именно из него копирую).