Ненаписанный языг программирования "Превед!".

Концепция строк.

Во всех существующих ЯП я испытываю проблему с "прожорливостью" строк, во всех, кроме си. Там их тупо нет. Но возникает попоболь манипулирования с массивами чаров. Строка - это всегда структура, как правило с массивом букв и длинной строки. Структуры аллоцируются в куче, порождая громадный своп в процессе их эксплуатации и часто являются самым узким местом как по потреблению памяти, так и по производительности, будучи помещенными в бесконечный цикл, чтения из сокета, например. Также, операции взаимодействия с библиотеками написанными на си - порождают операции копирования из структур в массив и обратно, зачастую сводя на нет преимущество библиотеки на си. Например в гоу, я просто вынужден их (строк) избегать, для избегания проблемы аллокаций и GC. В паскале подошли к проблеме радикально, зарезервировав первый байт под длину строки, но ограничив максимальный размер строки 255 байтами. Я думаю истина может быть посередине. При операциях с числами, практика резервирования типов в зависимости от размерности числа - общераспространенна и никого не смущает. В большинстве языков мы имеем int8, int16..int64 - и это правильно, так как на миллионных картеджах каждый байт превращается в гигабайт. Суть моей идеи состоит в следующем:

- Мы храним информацию о размере строки - непосредственно в массиве char
- Мы сохраняем нулевой байт в конце строки, для избежания memcopy при передаче в си и обратно
- Таким образом мы существенно экономим память, за счет отказа от структур и имеем все преимущества структур

Как это реализовано. Строки бывают следующих типов string8, string16, string32 и string.
string - является 64 битной строкой, и для 64 битов мы опускаем разрядность ( по аналогии можно поступить с int)
Допустим я хочу записать строку 'hello', в типе данных string8 она будет закодирована как в паскале:
5hello\0
где: 5 - длина строки, uint8, это первый байт (8 бит), затем строка и нултерминейтед байт, чтобы при передачи в си - можно было передать адрес не нулевого, а первого чара, без дополнительных конвертаций.

В случае 64 битной строки - у нас будет зарезервировано 8 байт под размерность.

Аллоцировать же память я предлагаю степенями двойки, следующая степень двойки, в которую поместится этот массив. Те при аллокации массива под строку hello в string8 - нам необходимо аллоцировать 5+2= 7, 2^3=8
Почему мы выравниваем память? Захваченную память по мере высвобождения проще переиспользовать, если она выровнена по степеням. Допустим я захожу создать строку pole - если память от hello уже высвобождена - я могу зареюзать любой слот подходящего размера (8байт) в данном случае. Не рвя память на "куски/фрагменты". Ну и хранить размер деаллоцированный области можно компактно в одном байте(размер - 2^256).

5 comments

>В случае 64 битной строки - у нас будет зарезервировано 4 байта под размерность.
Я считать разучился или всё же 64/8 = 8 байт под размерность.
И почему опускать 64 для просто string? А когда мы перейдем к ста двадцати восьми, как избегать путаницы?
C# и UTF, ага…

Хоть бери и тащи в каждый проект свою реализацию.
George Fedoroff
>В случае 64 битной строки - у нас будет зарезервировано 4 байта под размерность. Я считать разучился или всё же 64/8 = 8 байт под размерность. И почему опускать 64 для просто string? А когда мы перейдем к ста двадцати восьми, как избегать путаницы?
нет это я олень. Когда перейдем к 128 - будет путаница, да( С другой стороны писать string64, int64 - тоже длинно, мб надо добавить алиасы для распространенных, дефолтных типов или юзать разрядность системы как в гоу, там если на 32 запущен гоу - инт - 32 битный, но это тоже странно
Shannar de Kassal
C# и UTF, ага… Хоть бери и тащи в каждый проект свою реализацию.
в сишарп как раз как везде. Массив чаров + длина: A string is an object of type String whose value is text. Internally, the text is stored as a sequential read-only collection of Char objects. There is no null-terminating character at the end of a C# string; therefore a C# string can contain any number of embedded null characters ('\0'). The Length property of a string represents the number of Char objects it contains, not the number of Unicode characters. To access the individual Unicode code points in a string, use the StringInfo object.
кстати - по стоимости конвертаций в go https://github.com/mna/gocostmodel#example