уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

В последний раз я более менее подробно рассказывал о работе с JSON в Delphi года три назад, когда актуальной была Delphi XE2. Однако все течет, всё меняется и сейчас у нас уже есть Delphi XE7 с новыми возможностями, крутыми штуками типа AppTethering и FireUI, а вместе с этим и с менее заметными, но, тем не менее, серьезными изменениями в работе с JSON в Delphi.

Надо сказать, что с того момента, как в Delphi появилась своя собственная библиотека для работы с JSON, мы перевели абсолютно все свои компоненты для работы с онлайн-сервисами именно на работу с данными в формате JSON и, надо сказать, что ничуть не жалеем. Иногда по Сети приходится «ворочать» довольно большие объемы данных и компактный JSON тут оказывается как нельзя кстати. Однако, вместе с этим, не сильно торопились переезжать на новые версии Delphi — на момент написания этой статьи пока ещё используется Delphi XE3. Но в ближайшую неделю-две будет переезд на Delphi XE7 (надеюсь удачный). И так как переезд будет по-любому,  я решил проверить работу всех своих компонентов в XE7. 

Первое, что сразу становится понятным — это то, что теперь все классы для работы JSON «переехали» в модуль System.JSON. Переезд это произошел намного ранее, чем вышла XE7, но, когда точно сейчас сказать не могу…скорее всего в XE5. В общем переехали классы и бог с ними — пусть будет System.JSON. Так даже логичнее.

Просто, чтобы ни у кого не возникало лишних вопросов, договоримся сразу:

при дальнейшем рассмотрении работы с JSON я буду сравнивать, то, что было в Delphi XE3 и то, что стало в Delphi XE7, не рассматривая изменения во всех промежуточных версиях (Delphi XE4, Xe5, XE6).

Теперь посмотрим на изменения в классах.

У всех классов-наследников TJSONAncestor появился новый метод:

function ToJSON: string;

Метод, как можно догадаться из его описания, представляет какой-либо JSON-элемент в виде обычной строки. В принципе, причина появления этого метода мне не совсем ясна, т.к. у нас уже имеется метод ToString, который делает ровно то же самое.

 

В Delphi 10.3 Rio работа методов ToString и ToJson различная. Смотрите об этом подробнее в этой статье.

Серьезные изменения произошли в классе TJSONObject. Так один из методов Get и метод Size теперь помечены как deprecated:

function Get(const Index: Integer): TJSONPair; overload; deprecated 'Use Pairs property';
function Size: Integer; inline; deprecated 'Use Count Property';

Вместе с этим, для работы с парами и их значениями у нас теперь появились такие свойства:

property Count: Integer read GetCount;
property Pairs[const Index: Integer]: TJSONPair read GetPair;
property Values[const Name: string]: TJSONValue read GetValue;

Также появился новые метод:

function GetValue(const Name: string): TJSONValue; overload;

с помощью которого можно получить значение пары с именем Name.
Аналогичные изменения произошли и в классе TJSONArray. Так, помечены как deprecated:

function Size: Integer; inline; deprecated 'Use Count Property';
function Get(const Index: Integer): TJSONValue; deprecated 'Use Items property';

Вместо этого появились свойства:

property Count: Integer read GetCount;
property Items[const Index: Integer]: TJSONValue read GetValue;

Появились новые методы для работы с числами с плавающей точкой в JSON:

function FloatToJson(const Value: Double): string;
function JsonToFloat(const DotValue: string): Double;
function TryJsonToFloat(const DotValue: string; var Value: Double): Boolean;

Что дали в итоге эти и другие изменения в библиотеке для работы с JSON в Delphi? Как минимум более лаконичный и читабельный код.
Что же касается скорости работы, то здесь я был приятно удивлен тем, что в Delphi XE7 JSON стал парсится быстрее. В качестве примера я взял файл размером 61 Mb, содержащий массив на 10000 элементов. Каждый элемент — JSON-объект с различными данными. Чтобы проверить скорость парсинга я написал в XE3 и XE7 две абсолюно одинаковые прогаммки, следующего содержания:

var iCounterPerSec: TLargeInteger;
    T1, T2: TLargeInteger;
    Str: TStringStream;
    JSON: TJSONValue;
begin
  if OpenDialog1.Execute then
    begin
      Str:=TStringStream.Create;
      try
        Str.LoadFromFile(OpenDialog1.FileName);
 
        QueryPerformanceFrequency(iCounterPerSec);
        QueryPerformanceCounter(T1);
 
        JSON:=TJSONObject.ParseJSONValue(Str.DataString);
 
        QueryPerformanceCounter(T2);
        Label1.Caption:=FormatFloat('0.0000', (T2 - T1) / iCounterPerSec) + ' сек.';
      finally
        Str.Free;
      end;
    end;
end;
  • Результат в Delphi XE711,6139 сек.
  • Результат в Delphi XE315,8304 сек.

Разница более чем в 4 сек., по-моему, достаточно значительна. Что же касается моей проверки, то код XE3 скомпилировался без ошибок в Xe7. Конечно, пришлось убрать использование всех методов, которые помечены deprecated, чтобы не словить, например, в Delphi XE8 или XE10 (если когда-то будем переходить) неприятненькие сюрпризы в виде убранных методов. В целом же — с работой с JSON в Delphi XE7 всё супер.

5 1 голос
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
7 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Евгений
Евгений
04/11/2014 03:14

Не давно тоже заморачивался JSON, но стандартныя либа меня неустроила ни по скорости, ни по удобству работы, пришлось воять свою. Теперь все устраивает выложил может кому-то будет интересно https://sourceforge.net/projects/fastjsonlib/.

Евгений
Евгений
10/11/2014 18:38

Произвел некоторые оптимизации… Тестировал на файле 110Мб ~2,7 млн элементов получилось 3,8 сек.

Иван
Иван
20/03/2015 04:31
Ответить на  Евгений

Отличная библиотека. как по скорости, так и удобству. Стандартная и рядом не стоит. Есть правда небольшие косяки в ней, к примеру: procedure TJSONObject.Clear(var AStr: string); var tmpCur,tmpLength : integer; <--- не используются объявленные переменные в процедуре ----- vtPChar: tmpValue := '"' + AArray[I].VPChar + '"'; <---- кастинг string и ansichar по утечкам памяти все классно, чисто и опрятно, что не сказать про стандартную либу делфи. Хотел бы узнать, как с вами связаться ? Внедрил вашу библиотеку к себе в проект, просто шикарно . как по памяти, так и по производительности, хотел бы с вами периодически связываться, предлагать идеи, узнавать об… Подробнее »

Евгений
Евгений
23/01/2016 13:37
Ответить на  Иван

Привет. Сюда давно не заглядывал. Если нужно связаться jhonny_[собака]mail.ru

Андрей
Андрей
31/03/2015 22:38

Влад можно пример парсинга JSON для наглядности!

Виталий
Виталий
12/06/2015 21:08

Парсить массивы JSON получается нормально, а вот с этим разобраться не могу никак:
{«response»:{«upload_url»:»http:\/\/cs624121.vk.com\/upload.php?act=do_add&mid=308290015&aid=216925737&gid=0&hash=731e303939460cce672b572c9e3af472&rhash=2b8fa3ccc12301078edecdf00e330f39&swfupload=1&api=1″,»aid»:216925737,»mid»:308290015}}

Использую Dephi XE7
Везде примеры только с массивами JSON

Bssat
Bssat
24/09/2015 12:51

Fastjsonlib работает отлично и быстро. Однако, при разработке для андрюши, на хе8 не работает. На винде все нормально. На андрюше парсит не правильно.