ENERGY

[Статья] Ищем самый быстрый парсер JSON в Delphi

4 сообщения в этой теме

Друзья, нашел тут интересную статью, где тестируются разные jSON парсеры.

 

Ссылка: http://www.webdelphi.ru/2016/10/ishhem-samyj-bystryj-parser-json-v-delphi/

Автор: Владислав Баженов

Описание (26/10/2016):

Скрытый текст

В продолжение статьи об инструменте для просмотра JSON решил разобраться с вопросом: какой самый быстрый парсер JSON есть в Delphi? На сегодняшний день у Delphi-разработчиков более, чем достаточно различных библиотек для работы с JSON, в том числе имеются и «родные» классы для JSON. И хотелось бы узнать, какая из библиотек окажется самой быстрой.В качестве теста я решил проверить, как справятся библиотеки с парсингом файла, размером в 189 Мб (ссылка).

Библиотеки, которые тестировались:

Какие-то из этих библиотек развиваются и постоянно  дорабатываются, например, как x-SuperObject, а какие-то давно уже «умерли», но, тем не менее, на просторах Интернета о них упоминается чаще, чем о других может быть более новых библиотеках, о которых я не в курсе.

Тест проводился согласно демонстрационным примерам к библиотекам

В тесте я обращал внимание не только на время, которое потребуется библиотеке, чтобы распарсить большой файл, но и размер оперативной памяти, который займет программа после того, как библиотека справится с большим JSON. В «спокойном» состоянии тестовая программа занимает в оперативной памяти 1,4 Мб.

Работа каждой библиотеки проверялась трижды. После каждого вызова процедуры парсинга, тестовая программа полностью перезагружалась.

Вот какие результаты в итоге были получены:

Библиотека Время парсинга Объем занимаемой памяти, Mb
lkJson 00:00:13.9 1008,3
Delphi Web Utils 00:03:46.6 912,4
SuperObject Out of Memory
x-SuperObject Out of Memory
Fast JSON lib Программа зависла
System.JSON Out of Memory

Три библиотеки (SuperObject, System.Json и FastJson lib) не справились с разбором тестового файла.

При этом FastJSON lib на протяжении получаса «отъедала» 51,4% CPU и 911 Mb оперативной памяти, но так ничего и не распарсила.

x-SuperObject  справилась с задачей один раз, затратив на это чуть более 50 секунд, второй и третий разы выдала out of Memory.

SuperObject и System.Json сошли с дистанции практически сразу, выкинув перед этим «Out of Memory».

Из оставшихся самой быстрой оказалась библиотека lkJson, которая справилась с заданием за примерно 14 секунд и заняла в памяти чуть больше 1 Гб.

Delphi Web Utils затратила в 14 раз больше времени (3 минуты 46 секунд), но в памяти заняла примерно на 100 Мб меньше.

Что тут можно сказать…lkJson, как и Delphi Web Utils не обновлялись с 2013 года, однако с задачей парсинга большого JSON справились. Так что, если вы ищите небольшую, но достаточно быструю библиотеку для парсинга больших и очень больших JSON-объектов, то, думаю, что Вам стоит присмотреться к lkJson.

 

Изменено пользователем ENRGY
Rusland и Kitty понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

у меня XSO нормально 200 мб файл съел. и без проблем работал

Kitty понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Статья странная... Он каким то кодом как то протестировал парсинг. Что именно делалось не понятно. В разных библиотеках парсинг трактуется по разному, это может быть вообще проверка на валидность JSON (подсчет скобочек и двоеточий), а может быть полный разбор содержимого и загрузка в память.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
11 час назад, Евгений Корепов сказал:

Статья странная...

и однобокая.

Далеко не всегда есть необходимость парсить гигабайтные джейсоны. Чаще (имхо) бывает нужно обработать много достаточно маленьких, но с какой-нибудь структурой а-ля "массив объектов в объекте, который в...". Или быстро сформировать свой (много своих). И вот тут картина может поменяться.

Изменено пользователем kami
Евгений Корепов понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: unicorn
      Всем привет. 
      Мне нужно отправить запрос к серверу в формате JSON-RPC. Вопрос - как в него запихнуть json-данные правильно?
    • Автор: Просто Проги
      Пытаюсь получить список друзей из вк получаю их по api записываю в memo.text ответ от get запроса,после пытаюсь получить из json поля
      ответ выглядит так
      { "response": { "count": 104, "items": [ { "id": 1308603, "first_name": "Виктория", "last_name": "Талина", "photo": "http://cs625517.vk.me/v625517603/4e79b/E9Q1WA5SSLiI.jpg", "photo_100": "http://cs625517.vk.me/v625517603/4e79a/15QwerpQbCKk.jpg", "photo_400_orig": "http://cs625517.vk.me/v625517603/4e7199/wxOJQyZhqq8.jpg", "online": 0 }, { "id": 282070, "first_name": "Никита", "last_name": "Багров", "photo": "http://cs630623.vk.me/v630623070/4b610/RXNNdJ6_Nik.jpg", "photo_100": "http://cs630623.vk.me/v630623070/4b60f/MDXpi0deY1A.jpg", "photo_400_orig": "http://cs630623.vk.me/v630623070/4b60e/ec7A3pBDJZ0.jpg", "online": 0 }, "first_name": "Имя ", Следующим кодом
       
      var JSON: TJSONObject; JSONArray: TJSONArray; i: Integer; begin JSON := TJSONObject.ParseJSONValue(Form2.Memo2.Lines.Text) as TJSONObject; сюда получается я заношу весь код Form2.Memo2.Lines.Clear; JSONArray := TJSONArray(JSON.Get('items').JsonValue); далее изу по массиву итмемов for i := 0 to JSONArray.Size - 1 do begin Form2.Memo2.Lines.Add(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('first_name')).JsonValue.Value); пытаюсь добавить найденное поле end; но летят ошибка критичная (
    • Автор: rareMax
      Я работаю с библиотекой XSuperObject. Как правило, сам JSON я не парсю, а только создаю классы-прототипы данных в JSON, и пользуюсь методами .FromJSON и .ToJSON.
      пример:
      Для такого JSON'a 
      создаю такой класс:
      TvktStatus = Class private Ftext: String; FAudio: TvktAudio; published [Alias('text')] property text: String read Ftext write Ftext; [Alias('audio')] property audio: TvktAudio read FAudio write FAudio; End; в итоге не нужно парсить программисту - все делает библиотечка. 
      Теперь к самой проблеме.
      Допустим есть такой файлик с данными в формате JSON:
      Как бы вы составили такой класс-прототип? Ведь тут получается в одном массиве есть как число так и строка.
    • Автор: rareMax
      Поддерживает ли стандартная библиотека маршалинг/демаршалинг классов? Сейчас работаю с XSuperObject - работа очень приятная с ним. Но огорчает то, что тащит за собой тяжелые библиотеки(Инди, БД). Если нет - может кто знает альтернативы полегче? В идеале будет если так же будут Marshalling Attributes
    • Автор: MikeWuzHere
      Получаю с сервера большой JSON, в нем есть поле number. Как получить список в memo состоящий только из номеров? Подскажите пожалуйста..
       
    • Автор: Dion
      Добрый день, Господа.
      Давайте меняться. 
      Предлагаю вам откуда-то взятый мною superobject, версии 1.2 из которой я выкинул разный хлам, допилил и сделал так, чтобы он собирался под Android, OS X и iOS. Протестировал.
      Дальше я написал вокруг него километр кода, создал набор стилей и сделал динамическую загрузку стилей для списка. В список в соответствии со стилями можно добавить порядка 20 разных компонентов.
      Идея моя была такой.
      Есть сервер, на него с клиента загружаются стили и дальше они разливаются от сервера к серверу и в конечном счете попадают на клиентов. Грубо говоря, должен получиться тонкий клиент.
      Надо кому? 
    • Автор: Axbor
      TJSONObject *o = dynamic_cast<TJSONObject*> (TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(s), 0)); if (!o) return; TJSONArray *a = dynamic_cast<TJSONArray*>(o->Get("M")->JsonValue); if (!a) return; for (int i = 0; i < a->Count; i++) { TJSONObject *b = dynamic_cast<TJSONObject*>(a->Get(i)); if (! return; Jokes[i + CurrPos].Caption = b->Pairs[0]->JsonValue->ToString(); Jokes[i + CurrPos].Content = b->Pairs[1]->JsonValue->ToString(); Count++; } delete L; L = 0;  "s" это текст которая хранит JSON внутри значений которого есть символ " (кавычка). В JONS е уже добавлены BackSlash перед такими символами. При парсинге JOSN опят добавляются BackSlash перед спец символами. Как от этого избежать?
    • Автор: Syb
      Я могу совсем что то не правильно делать, хочу получить данные согласно API :
       
       
      http://glonasssoft.ru/wiki/?wiki_name=API
      var jValue:TJSONValue; s,s1:string; begin RestClient1.BaseURL:='http://dev.glonasssoft.ru/auth/login'; Restrequest1.Execute; jValue:=RESTResponse1.JSONValue; s:=jValue.ToString; s1:= copy(s,pos('AuthID:"',s)+11,pos('","U',s)-pos('AuthID:"',s)-11);//достал ключ RestClient2.BaseURL:='http://dev.glonasssoft.ru/vehicles_'; Restrequest2.Params[0].Value:=s1; -здесь параметр типа HttpHeader задан X-Auth в него сую ключ Restrequest2.Execute; - говорит не авторезирован jValue:=RESTResponse2.JSONValue; s:=jValue.ToString; что я не так делаю?
    • Автор: Равиль Зарипов (ZuBy)
      Привет Всем!
       
      Решил поделится впечатлениями по работе с SuperObject'ом и родным JSON'ом
       
      тест был файла с 2000+ объектами в JSON файле
      структура файла была такая
      { "status":"OK", "last_id":"711", "objects":[ { "obj_id":"1", "obj_acc_id":"1", "obj_cat_id":"24", "obj_title":"13 магистраль", "obj_descr":"ЖК представляет собой комфортный дом, состоящий из 14 блок-секций (подъездов). Расположен в перспективном развивающемся районе по 13 Магистрали с удобным выездом как на левый берег, так и в старую часть города. Вблизи Жилого комплекса распологается новая школа, парк отдыха и культуры.", "obj_address":"ул. Мамышулы - 104, д. 16\/1", "obj_address2":null, "obj_url":"3fa07dd73be072b049529c80c7d74732", "obj_planet":"1", "obj_country":"1", "obj_region":"1", "obj_city":"292", "obj_lat":"51.141", "obj_lon":"71.4835", "obj_insert_dt":null, "obj_update_dt":null, "obj_editted":"0", "obj_updated":"0", "obj_deleted":"0", "obj_showed":"1", "obj_rating":"0", "obj_pro_top":"0", "obj_pro_selected":"0", "obj_pro_unix_dt":"0", "obj_partner":"0", "obj_parent_id":"0", "obj_has_child":"0", "obj_currency":"0" }, // тут далее 2000+ объектов ] } SuperObject  Время выполнения:  ~01:393
      JSON родной Время выполнения: ~01:690
       
      разница не особо ощутима, тем более если будет меньше объектов
       
      JSON родной
      function JSONParse(const aJSONData: string; const aMemo: TMemo): boolean; var aJSValue: TJSONValue; aJSObject, aJSObjArr: TJSONObject; aJSArray: TJSONArray; I: integer; begin Result := false; aJSValue := TJSONObject.ParseJSONValue(aJSONData) as TJSONValue; if Assigned(aJSValue) then begin aJSObject := aJSValue as TJSONObject; aMemo.Lines.Add('status: ' + aJSObject.GetValue('status').Value); if aJSObject.GetValue('status').Value = 'OK' then begin Result := true; if Assigned(aJSObject) then begin aJSArray := aJSObject.GetValue('objects') as TJSONArray; if Assigned(aJSArray) then begin Result := true; aMemo.Lines.Add('last_id: ' + aJSObject.GetValue('last_id').Value); aMemo.Lines.Add('count: ' + aJSArray.Count.ToString); for I := 0 to aJSArray.Count - 1 do begin aJSObjArr := aJSArray.Items[I] as TJSONObject; if Assigned(aJSObjArr) then begin aMemo.Lines.Add(aJSObjArr.GetValue('obj_id').Value + ',' + aJSObjArr.GetValue('obj_acc_id').Value + ',' + aJSObjArr.GetValue('obj_cat_id').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_title').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_descr').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_address').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_url').Value); end; end; end; end; end; aJSValue.Free; end; end; SuperObject
      function JSONSOParse(const aJSONData: string; const aMemo: TMemo): boolean; var xObject: ISuperObject; xCount, I: integer; sfmt: string; begin Result := false; xObject := SO(aJSONData); aMemo.Lines.Add('status: ' + xObject['status'].AsString); if xObject['status'].AsString = 'OK' then begin Result := true; xCount := xObject['objects'].AsArray.Length; aMemo.Lines.Add('count: ' + xCount.ToString); aMemo.Lines.Add('last_id: ' + xObject['last_id'].AsInteger.ToString); for I := 0 to xCount - 1 do begin aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_acc_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_cat_id"'].AsInteger.ToString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_title"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_descr"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_address"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_url"'].AsString); end; end; end; Разница ощутима когда пишешь код, SO намного легче читать
       
      Подробней почитать и скачать SO
    • Автор: rareMax
      Необходимо распарсить JSON в котором есть массив. Искал в интернете - но там для сторонних библиотек. 
      Вот сам объект в котором есть массив:
      { "Version": "1", "Charset": "UTF-8", "Variables": { "cookiepre": "1ati_2132_", "auth": "2ab39ybBCy0KypS2Sh6Ey5facuaHGKSG/9uhrV0JHzcirqQX+fl2nFUErSIpvOwZJuGURxqrJ9arNTPGkIiZ", "saltkey": "C6bK667j", "member_uid": "3", "member_username": "Maximum", "groupid": "2", "formhash": "e2b42ccc", "ismoderator": null, "readaccess": "150", "notice": { "newpush": "0", "newpm": "0", "newprompt": "0", "newmypost": "0" }, "list": [ { "uid": "5", "username": "Player" }, { "uid": "12", "username": "RaR" }, { "uid": "29", "username": "prlzrak" }, { "uid": "63", "username": "Leemur" } ], "count": "4" } } Вот тут мне надо помощь с парсингом list.
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу