Эффективность сериализации объекта в indexedDB verus JSON.stringify - PullRequest
0 голосов
/ 03 июня 2018

Меня интересует различие в эффективности браузера / ЦП / памяти между этапом сериализации JSON.stringify по сравнению с записью объекта в хранилище объектов в indexedDB.

Мотивация иликонтекстом для вопроса является запись объекта из базы данных на жесткий диск клиента наиболее эффективным способом.Для этого объект извлекается с помощью инструкции get и записывается в объект, этот объект преобразуется в строку с помощью JSON.stringify, а затем записывается в виде текста на диск.Я предполагаю, что оператор get десериализует объект из его сериализованной формы в базе данных.Если это так, то объект не сериализуется из формы indexedDB, а затем сериализуется в форму JSON.stringify.

Затем для восстановления данных с диска файл читается, текст преобразуется в объект с помощью JSON.parse.и объект добавляется или помещается в базу данных, что, по-видимому, требует еще одного шага сериализации.Итак, строка JSON анализируется для объекта и затем сериализуется в форму indexedDB.

Первая часть моего вопроса заключается в том, можно ли получить объект из базы данных в его сериализованной форме, чтобы его можно было сохранить вдиск в том же виде и снова записывается в базу данных без необходимости выполнять промежуточные шаги stringify / parse?

Вторая часть вопроса, если это невозможно, и для специальныхВ случае использования indexedDB без какой-либо индексации и никогда не запрашивать данные по какому-либо значению, кроме уникального уникального ключа вне строки, есть ли какое-либо преимущество для хранения в базе данных строкового объекта, а не объекта?В сценарии запись / чтение на диск не будет включать промежуточные этапы stringify / parse и не будет никакого шага десериализации / сериализации, когда строка получена / помещена в базу данных, так как она не является объектом.Однако для изменения значения в одной из этих строк в базе данных потребуется JSON.parse для результата get, чтобы преобразовать его в объект, а затем JSON.stringify после изменения значения перед тем, как строка будет возвращена вбаза данных.

Но как сравнить JSON.parse и JSON.stringify с десериализацией и повторной сериализацией объекта базы данных при использовании get и put на объекте?Я подумал, что для сериализации объекта в indexedDB потребуется больше, чем JSON.stringify, поскольку первый может быть запрошен по его свойствам.

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

РЕДАКТИРОВАТЬ

Очевидно, если я правильно понимаю, алгоритм структурированного клонирования используется для хранения объектов в indexedDB;но этот результат все еще сериализован перед сохранением?и JSON использует лексическую грамматику, но никогда не копирует объект.

Возможно, я просто очень запутался, и при записи в indexedDB не происходит никакого шага сериализации, и наблюдаемое мной увеличение использования ОЗУ заключается в клонировании объекта, который затем сохраняется как объект.Если это так, то первая часть вопроса не имеет никакого смысла, потому что объект базы данных всегда нужно преобразовывать в строку для сохранения на диск.И вторая часть моего вопроса стала бы более требовательной к браузеру: 1) преобразовать объект в строку или клонировать его и 2) извлечь объект из базы данных, а не извлечь строку (если она была сохранена в виде строки JSON) и проанализировать ее?

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

Спасибо.

1 Ответ

0 голосов
/ 04 июня 2018

Преобразование объекта в строку и сохранение строк в базе данных не дает никакого преимущества в производительности.Преобразование объекта в строку с использованием JSON.stringify only увеличивает количество необходимых шагов.Я настоятельно рекомендую не делать этого, даже не пытаться сделать это, и не пытаться перехитрить реализацию indexedDB в C ++.

Сериализация indexedDB происходит в C ++, а не в js.JSON.stringify происходит в js, а не в C ++.В большинстве случаев все, что происходит в js, на несколько порядков медленнее, чем в C ++.

Строка js является объектом js.Если я правильно помню, вы не можете сохранить строку как объект в indexedDB, потому что она сама является функциональным объектом, а не простым объектом.Еще один способ заявить об этом - подумать об иерархии типов объектов.Все простирается от Object.Function простирается от объекта.String простирается от Function (ну, может быть, не прямо и не явно, но, тем не менее, эффективно).Любой потомок, который простирается от Function, такой как что-либо созданное с использованием class Foo или function Foo() {}; new Foo(); или new Function('foo');, не сериализуем.Все, что расширяется от Object без расширения от Function, является сериализуемым.

Функции не сериализуемы, как объяснено в моем ответе на ваш другой вопрос.

Когда вы создаете объект js с помощью object literal синтаксис, это всего лишь синтаксический сахар приблизительно для new Object(), а не function Foo().Такие объекты легко сериализуемы, потому что они в основном просто словари.То есть до момента, когда вы присоединяете метод.Метод снова является не чем иным, как функцией, которая связана как свойство с объектом.Поскольку даже простой объект с хотя бы одним методом больше не может быть сериализуем.

Вместо того, чтобы пытаться сохранить строку непосредственно в indexedDB, так как сам объект (потомок Function), вы можете сохранить толькоstring как свойство некоторого другого объекта, который не является функциональным объектом, потому что indexedDB явно знает тип String и явно заявляет о поддержке хранения свойств объекта со строковыми значениями, потому что он знает, как привести такие значения во время сериализации.

Алгоритм структурированного клонирования был переименован некоторое время назад.Теперь это алгоритм сериализации или что-то вроде «передаваемого» алгоритма, я забыл.

Когда вы сохраняете объект в indexedDB (например, {x:1,y:2}), он будет отправлен из JS в C ++, а затем в C ++ он будет сериализован.Когда вы извлекаете объект из indexedDB, то в C ++ он находит объект в его последовательной форме, десериализует его, затем передает его в JS, а затем JS передает его вам (вашей функции или возвращаемому значению, что угодно).Хотя сериализация более конкретно относится к преобразованию другого типа в строку, вы также можете использовать ее более широко для обозначения обоих направлений, поэтому имейте в виду, что сериализация, упомянутая где-либо в технических документах, может фактически говорить о десериализации.

Эта сериализация C ++ не обязательно от объекта к строке или строки к объекту, но к некоторому оптимизированному байтовому формату.В земле C ++ иногда менее полезно различать строки и другие типы значений, потому что строка - это просто одно произвольное представление байтов.Поэтому, когда мы говорим о сериализации в C ++, мы просто говорим об изменении представления абстрактной группы байтов.Очень похоже на то, как структура в C является просто представлением последовательности байтов, разбитых на части.В некотором смысле в C ++ под строкой можно понимать абстракцию с нулевой стоимостью в зависимости от того, как она используется.Фактически, вызов некоторой группы байтов того или иного типа на самом деле служит только для выяснения, какие операции должны вызываться для этих байтов и как эти байты должны что-то значить.В некотором смысле здесь сериализация может фактически вызывать одну и ту же последовательность байтов под другим именем, фактически не выполняя никакой обработки!Фактически, вы могли быть свидетелями этого, если когда-либо открывали двоичный файл в текстовом редакторе или открывали неправильно закодированную (или интерпретацию кодировки) веб-страницу.Так что, если вы говорите о разной производительности, то сравнение 0-шаговой операции с n-шаговой операцией дает очевидный ответ.

При этом, по иронии судьбы, сериализация в C ++ может в конечном итоге привести к преобразованию в строкукто знает, вы не должны знать, что это зависит от реализации indexedDB C ++, чтобы решить это, абстрагироваться от вас и скрыть его сложность.Существуют и другие типы проблем с эффективным хранением группы байтов, которые выходят далеко за пределы производительности сериализации.

Подводя итог, можно сказать, что в C ++ сериализация имеет другое значение, чем то, что JSON.stringify означает в Javascript.Преобразование значения в строку в js только замедлит вашу программу.Пусть indexedDB позаботится об этом для вас.

...