Как стать автором
Обновить

Комментарии 17

В 90е никто в критических по производительности местах токены никуда не перекладывал, все старались делать за один проход конечным автоматом, символ за символом, без malloc

Писал как-то себе xml-sax парсер на сях (да, ещё один :)) Он при работе просто конечным автоматом размечал нулями конец строк в буфере и коллекционировал ссылки начала строк. Работало быстро. Но он был не утф. По тз там однобайтовая кодировка была.

А расскажите пожалуйста, в чём преимущество перед стандартным парсером из System.Text.Json? Есть ли бенчмарки? Кажется, что даже десятки мегабайт, прочитанные один раз (речь ведь про настройки) не должны стать проблемой

А расскажите пожалуйста, в чём преимущество перед стандартным парсером из System.Text.Json?

Преимущество в том, что такой парсер работает в любой версии Unity и как и .NET. Этот парсер часть генерируемого кода тулы для чтения игровых конфигов. Мне неизвестно, где незвестно где этот код будет запущен. Оно плавно деградирует (через #if) до самых плохих условий исполнения и работает везде. В то время как System.Text.Json хочет свои зависимости и правильный рантайм со Span и ReadOnlySequence.

Есть ли бенчмарки?

Только что сделал 10mb JSON на .NET Framework 4.7.1 (Core могут быть чуть другие результаты):

| Method                         | Mean     | Error    | StdDev   | Ratio | RatioSD | Gen0      | Gen1     | Gen2     | Allocated | Alloc Ratio |
|------------------------------- |---------:|---------:|---------:|------:|--------:|----------:|---------:|---------:|----------:|------------:|
| JsonFormatter                  | 74.45 ms | 1.163 ms | 1.384 ms |  1.03 |    0.03 | 3714.2857 | 142.8571 |        - |  23.82 MB |        1.05 |
| SystemTextJsonFormatter        | 72.40 ms | 0.607 ms | 0.538 ms |  1.00 |    0.00 | 3714.2857 |        - |        - |  22.64 MB |        1.00 |
| JsonFormatterWithStringPooling | 65.76 ms | 0.743 ms | 0.695 ms |  0.91 |    0.01 | 2500.0000 | 750.0000 | 250.0000 |  14.98 MB |        0.66 |

Кажется, что даже десятки мегабайт, прочитанные один раз (речь ведь про настройки) не должны стать проблемой

Вот это только токенизация 10Mb JSON т.е. "Read() + reader.GetString()/GetInt()", а еще сколько занимает создание объектов и складывание в них. Представьте теперь вместо моего современного PC процессора мобильный процессор который троттлится от жары.

А зачем вы тогда используете формат json, а не готовую структуру байт которую можно замаппить в самом приложении, и тут не будет никакого лишнего парсинга.

Ну используйте свой json и храните его в гите, а при билде в приложение подсовывать готовое упакованное представление. И зачем тогда нужны все эти оптимизации?

У каждого разработчика игр свой ответ на этот вопрос. За очень редким исключением большинство выбирают текстовые форматы для хранения игровых конфигов.

Мои ответы:
а) один источник правды - сам JSON/YAML/INI/CSV файл
б) возможность по-быстрому подправить и перезапустить игру без экспортов в бинарный формат
в) возможность моддерам без доп инструментов что-то добавить/убрать/затюнить

Видел тот код. Автор simdjson мыслил другими категориями и понятиями пока недостижимыми для меня. Там весь токенизатор это две инструкции лукапа по таблицам, и никаких стейт машин.

Возникает вопрос, может быть стоит конвертировать данные в более удобный для машины бинарный формат?

Да, есть еще вариант хранить в формате MessagePack, и даже есть парсер который в 2.7х быстрее чем JSON. Но у бинарных форматов есть огромный минус, они плохо диффятся и мержатся в системах контроля версий. Даже без мержей, просто посмотреть что поменялось в бинарном файле невозможно.

simdjson уже упомянули, бинарные форматы упомянули, остаётся ещё yyjson упомянуть. Ну и конечно в статье про улучшение производительности очень нехватает результатов замеров до и после (и в процессе), понять получилось быстро или медленно (относительно лучших существующих решений) невозможно. О файлах какого размера речь хотя бы идёт? И о каком времени обработки? И что мешает взять существующие библиотеки в проект, где важна производительность?

Ну и конечно в статье про улучшение производительности очень нехватает результатов замеров до и после (и в процессе), понять получилось быстро или медленно (относительно лучших существующих решений) невозможно. О файлах какого размера речь хотя бы идёт? И о каком времени обработки? И что мешает взять существующие библиотеки в проект, где важна производительность?

В комментарии https://habr.com/ru/articles/828502/comments/#comment_27035122 есть ответы на все эти вопросы и бенчмарк.

Это смешно без тестов скорости. И что значит парсинг? - в структуру? В интерфейс? В переменные? Сколько строк в секунду этот парсер обрабатывает?

Как только в unity завезли парсинг напрямую из Span, я переписал сериализаторы практически без выделений.

Основа это два класса, где внутри данные на основе чанков. Первый это структуры нодов, второй это куски байт данных.

При парстнге строится дерево в глубину. Ссылки на данные по индексу во втором классе.

Если данные это строки, то да, создается string. А если нет, то парсится, без лишних преобразований.

Первый это структуры нодов, второй это куски байт данных.

Второй ReadOnlySequence<T> который набор сегментов с ссылкой на Next. А можете показать код первого для изучения, если это не секрет.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории