byte_size против String.length в эликсире - PullRequest
0 голосов
/ 13 марта 2019

Я решил создать свой собственный анализатор CSV в эликсире в качестве учебного проекта и сумел заставить что-то работать без особых хлопот.

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

Iначал искать исходный код модуля эликсира NimbleCSV .Он был написан Хосе Валимом, создателем языка, с участием нескольких известных разработчиков эликсира, поэтому я подумал, что это хороший выбор.

В функции parse_string они проверяют длину строк с помощьюфункция byte_size(string).Я думаю, что понимаю, как работает эта функция.Например,

iex()> byte_size(<<104, 101, 108, 108, 111>>)
5
iex()> byte_size(<<104, 101, 108, 108, 111::9>>)
6

Первая функция - 40 bits, которая равна 5 bytes (каждое значение в двоичном файле по умолчанию равно 8 битам в эликсире, если не указано иное)

Во втором яприсваивая одному из значений 9 bits, таким образом, итоговое значение составляет 41 bits.Это означает, что это 6 bytes (из-за округления)

извините, если какой-то язык не совсем правильный

Это имеет смысл для меня.Мой вопрос, почему они выбрали бы эту функцию вместо String.length в этом случае?Если они просто получают длину строки, оба не вернут одинаковый результат?

1 Ответ

3 голосов
/ 13 марта 2019

String.length/1 возвращает числа графем (каждый может содержать один или несколько байтов), тогда как byte_size/1 имеет дело с байтами необработанных данных.

iex> byte_size "?‍?‍?"
18
iex>  "?‍?‍?" <> <<0>>
<<240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 167, 0>>

iex> String.length "?‍?‍?"
1

iex> String.length "a"
1
iex> byte_size "a"
1

из документа :

Строковые и двоичные операции

Чтобы действовать в соответствии со Стандартом Юникода, многие функции в этом модуле выполняются за линейное время, так как им необходимо пройти всю строку с учетом правильных кодовых точек Юникода.

Например, String.length/1 займет больше времени при увеличении ввода. С другой стороны, Kernel.byte_size/1 всегда выполняется в постоянное время (т.е. независимо от размера ввода).

Не имеет отношения к делу, но если вы хотите узнать больше о Unicode и кодировке символов, вы можете прочитать эту статью и посмотреть это видео

...