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

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

А теперь сравните с fastJSON, пожалуйста.

Я установил nuget-пакет отсюда и обновил код бенчмарков: deserialization и serialization. Так как я не знаю обычных способов использования fastJSON, то я пошёл по пути наименьшего сопротивления: в библиотеке есть статический класс JSON с двумя методами — ToObject и ToJson. Я использовал именно их. Возможно, вы подскажете какие-то более оптимальные способы.

Результаты тестирования для десериализации (таблицу вставить почему-то не получилось):
Newtonsoft: 1.00 (аллокация 35.47 MB)
FastJson: 0.97 (аллокация 48.81 MB)
JDeserializer: 0.42 (аллокация 12.36 MB)

Результаты тестирования для сериализации:
Newtonsoft: 1.00 (аллокация 25.44 MB)
FastJson: 1.21 (аллокация 54.8 MB)
JSerializer: 0.38 (аллокация 5.93 MB)

странно, у меня fastJSON работает где то в 20 раз быстрее Newtonsoft (на десериализацию). но спасибо за тесты.

Хм. Конечно, было бы здорово сделать бенчмарк и дать ссылку на него код, но если вам не удобно, то хоть примерный код набросайте — как вы это делаете?

Ещё у меня есть проблема с примерами. Я вот бегло посмотрел «Using the code» на странице проекта, и там написано:

var newobj = fastJSON.JSON.Instance.ToObject(jsonText);

Но в static-классе JSON нет свойства Instance. Возможно, у вас какой-то другой код? Может быть, вы дадите ссылку на nuget? Как я уже писал, я взял вот отсюда (версия 2.2.4). Если перейти с nuget на страницу проекта — то это именно та, которую вы дали.

я просто использую JSON.ToObject<T>(data), версия 2.2.4, пакет вроде тот же.

НЛО прилетело и опубликовало эту надпись здесь
Я извиняюсь, но при виде try {… } catch (e) { return null; } у меня жутко дергается глаз.
НЛО прилетело и опубликовало эту надпись здесь
Если где-то в коде перехватывается любой тип ошибки, не логируется и происходит подмена результирующих данный (здесь возврат NULL) — это путь к долгим отладкам и не тривиальным ошибкам.
НЛО прилетело и опубликовало эту надпись здесь
Неплохо было бы сравнить и Майкрософтовскую версию, только тут придется играться с .NET Core 3.0 preview.
www.nuget.org/packages/System.Text.Json
Да, я думал об этом и даже набросал небольшие тесты в отдельной ветке. Тот, который System.Text.Json.JsonSerializer работает очень хорошо. Максимальную производительность, судя по документации, должна обеспечивать работа с Utf8JsonReader — но до её тестирования пока руки не дошли.

Тестирование производилось на следующей конфигурации (так как мы имеем дело с preview, то привожу её полностью):
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17134.81 (1803/April2018Update/Redstone4)
Intel Core i5-7400 CPU 3.00GHz (Kaby Lake), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=3.0.100-preview8-013656

[Host]: .NET Core 3.0.0-preview8-28405-07 (CoreCLR 4.700.19.37902, CoreFX 4.700.19.40503), 64bit RyuJIT
Core: .NET Core 3.0.0-preview8-28405-07 (CoreCLR 4.700.19.37902, CoreFX 4.700.19.40503), 64bit RyuJIT

Job=Core Runtime=Core

Десериализация (.NET Core 3.0 preview):
Newtonsoft: 1 (allocation 34.87 MB)
VNext: 0.76 (allocation 9.3 MB)
Velo: 0.39 (allocation 11.37 MB).

Сериализация:
Newtonsoft: 1 (allocation 24.85 MB)
VNext: 0.82 (allocation 16.59 MB)
Velo: 0.37 (allocation 5.91 MB).

Думаю, что можно уже готовиться переходить на System.Text.Json.JsonSerializer. Из коробки он работает значительно лучше Newtonsoft: аллокация при десериализации очень низкая — как минимум GC будет благодарен.
Есть еще SpanJson. Тот еще велосипед, судя по оформлению истории комитов, но зато поддерживает аттрибуты-конвертеры.

Набросал бенч на коленке сериализацию и десериализацию и получилось:

core 2.2.2

Newtonsoft: 1 (allocated 35.48 MB)
Velo: 0.43 (allocation 12.36 MB)
SpanJson: 0.18 (allocation 2.75 MB)

Newtonsoft: 1 (allocated 25.45 MB)
Velo: 0.36 (allocation 5.93 MB)
SpanJson: 0.27 (allocation 4.4 MB)

Оптимизируйте решение, токены вообще не нужно в памяти хранить

Возможно, вы укажете кусок кода, который вас смутил?

Я нигде не храню токены. JsonTokenizer специально построен как IEnumerator — токены считываются из исходной строки сразу и передаются потребителю.
var tokens = new List();
В статье есть.

Извиняюсь, прочитал просто до этого момента и дальше не стал читать.
Мне еще [де]сериализатор от facebook нравится — github.com/facebook-csharp-sdk/simple-json тоже достаточно простой.
Исходник одним файлом, можно затащить к себе (MIT лицензия).
Я, наверно, вас расстрою. Бегло посмотрев код я заподозрил, что данный [де]сериализатор будет очень много аллоцировать. Собственно, так оно и оказалось. Я обновил бенчмарки сериализации и десериализации.

Десериализация:
Newtonsoft: 1 (аллокация 35.47 MB)
SimpleJson: 1.81 (аллокация 667.02 MB)
Velo: 0.43 (аллокация 12.36 MB)

Сериализация:
Newtonsoft: 1 (аллокация 25.44 MB)
SimpleJson: 1.15 (аллокация 72 MB)
Velo: 0.39 (аллокация 5.93 MB)

Я скопировал файл SimpleJson и добавил его в проект. Ничего не менял.

При такой аллокации его использовать просто опасно. В бенчмарке всего 10 000 элементов, которые де/сериализуются. Тратить на такую простую операцию 600 мегабайт — очень сомнительное удовольствие.
Занятно, что подобную методологию десериализации/обработки данных с минимальными издержками по памяти уже давно придумали использовать для XML и имя ей SAX.
Как говорится: Всё новое — хорошо забытое старое.
Тут про совсем противоположное SAX — как перегнать в DOM (в объекты) самым быстрым способом.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории