代码之家  ›  专栏  ›  技术社区  ›  Gary

对象序列化到indexeddb verus json.stringify的效率

  •  2
  • Gary  · 技术社区  · 8 年前

    我感兴趣的是json.stringify的序列化步骤与将对象写入indexeddb中的对象存储的序列化步骤在浏览器/cpu/memory的效率方面的差异。

    问题的动机或上下文是以最有效的方式将对象从数据库写入客户机的硬盘驱动器。为此,使用get语句检索对象并将其写入对象,使用json.stringify将该对象转换为字符串,然后将其作为文本写入磁盘。我假设get语句从数据库中的序列化形式取消对象的序列化。如果是,则对象将从indexeddb form取消序列化,然后序列化为json.stringify form。

    然后从磁盘恢复数据,读取文件,用json.parse将文本转换为对象,并将对象添加或放入数据库,这似乎需要另一个序列化步骤。因此,json字符串被解析为一个对象,然后序列化为indexeddb格式。

    我的问题的第一部分是,是否可以从数据库中以序列化的形式检索对象,以便以相同的形式将其保存到磁盘,然后再次写入数据库,而不必执行stringify/parse的中间步骤?

    问题的第二部分是,如果不可能这样做,并且对于在没有任何索引的情况下使用indexeddb并且从不使用除越行唯一键以外的任何值查询数据的特殊情况,将字符串化对象存储到数据库而不是注入?

    在这种情况下,对磁盘的写入/读取将不涉及中间的stringify/parse步骤,并且在将字符串获取/放入数据库时不会有非序列化/序列化步骤,因为它不是对象。但是,要在数据库中更改其中一个字符串中的值,需要对get的结果进行json.parse以将其转换为对象,然后在值更改后再进行json.stringify,然后将字符串放回数据库。

    但是json.parse和json.stringify与使用get和put对数据库对象进行非序列化和重序列化相比如何呢?我认为将对象序列化为indexeddb需要的不仅仅是json.stringify,因为前者可以通过其属性进行查询。

    我将进行实验,看看差异是否可以观察到,但我想问一个了解这两种序列化的内部工作原理的人,在本例中,是否存在使用一种方法而不是另一种方法的潜在原因。

    编辑

    显然,如果我理解正确,结构化克隆算法用于将对象存储在indexeddb中;但是在存储之前,该结果是否仍然序列化?json使用词法语法,但从不复制对象。

    也许,我只是很困惑,在编写indexeddb时没有序列化步骤,而且我观察到的ram的增加使用是克隆对象,然后将其存储为对象。如果是这样,那么问题的第一部分就毫无意义,因为数据库对象将始终需要转换为字符串以保存到磁盘。我的问题的第二部分将成为浏览器的更高要求:1)将对象转换为字符串或克隆它;2)从数据库检索和对象,而不是检索字符串(如果保存为json字符串)并对其进行解析?

    在找到更多关于这方面的信息后,虽然其中大部分都是我想不通的,但我不确定这个问题是否值得考虑。

    谢谢您。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Josh    8 年前

    将对象转换为字符串并在数据库中存储字符串对性能没有好处。使用json.stringify将对象转换为字符串 只有 添加到必须发生的步骤数。我强烈建议不要这样做,甚至不尝试这样做,也不要试图超越C++中的索引XDB实现。

    DeloDeDB序列化发生在C++中,而不是JS。JSON.StrugI化发生在JS中,而不是C++。大多数情况下,发生在JS中的任何事情都比C ++慢了一个数量级。

    js字符串是js对象。如果我没记错的话,您不能将字符串作为对象存储在indexeddb中,因为它本身是一个函数对象,而不是一个普通对象。说明这一点的另一种方法是考虑对象类型层次结构。一切都从 Object . Function 从对象扩展。 String 延伸自 功能 (好吧,也许不是直接的,也不是明确的,但还是有效的)。任何从 功能 ,例如使用 class Foo function Foo() {}; new Foo(); new Function('foo'); ,不可序列化。任何从 对象 不延伸自 功能 是可序列化的。

    函数不能序列化,正如我在回答您的另一个问题时所解释的。

    当您使用 对象文字 语法,这仅仅是 new Object() 不是 function Foo() . 这样的对象很容易序列化,因为它们基本上只是字典。也就是说,直到你附加了一个方法。方法也不过是作为属性绑定到对象的函数。因为即使是至少有一个方法的纯对象也不再是可序列化的。

    而不是尝试将字符串直接存储在indexeddb中,因为它本身是一个对象( 功能 ,您只能将字符串存储为其他某个不是函数对象的对象的属性,因为indexeddb对字符串类型有明确的了解,并明确声明支持使用字符串值存储对象属性,因为它知道如何在序列化期间强制此类值。n.名词

    结构化克隆算法不久前被重命名。我忘了,现在是序列化算法或类似“可转移”算法的东西。

    在indexeddb中存储对象时(例如 {x:1,y:2} 它将从JS发送到C++,然后 C++内部 它将被序列化。当从索引XDB中检索对象时,在C++中,它将以串行形式查找对象,反序列化它,然后将其传递给JS,然后JS将它传递给您(您的函数或返回值)。尽管序列化更具体地指另一种类型到字符串的转换,但您也可以更一般地使用它来指两个方向,因此请记住,技术文档中任何地方提到的序列化实际上都是在谈论反序列化。

    这个C++序列化不一定要从对象到字符串或对象到字符串,而必须是某种优化的字节格式。在C++领域中,区分字符串和其他值类型有时不太有用,因为字符串仅仅是字节的任意表示。因此,当我们讨论C++中的序列化时,我们只讨论改变一组抽象字节的表示。很像c中的struct只是一个字节序列的表示,这些字节被分成几个部分。在某种意义上,在C++中,字符串可以理解为零成本抽象,取决于它是如何使用的。事实上,以一种或另一种类型调用某组字节只会澄清应该对这些字节调用哪些操作,以及这些字节应该如何表示某些内容。从某种意义上说,这里的序列化实际上可能只是用不同的名称调用相同的字节序列,而根本不执行任何处理!事实上,如果您曾经在文本编辑器中打开过二进制文件,或者打开过错误编码(或解释编码)的网页,您可能已经看到了这一点。所以,如果你说的是性能上的不同,那么,比较0步操作和n步操作会得到一个明显的答案。

    也就是说,C++序列化可能会最终发生转换为字符串,谁知道,你不应该知道,这取决于索引XDB C++实现来决定这一点,并将它抽象出来并隐藏它的复杂性。在高效存储一堆字节方面还有其他所有类型的问题,这些字节的长度远远超出了序列化性能。

    总而言之,序列化在C++中的含义与JSON.StrugI化在JavaScript中的含义不同。在js中将一个值转换成一个字符串只会减慢程序的速度。让indexeddb来照顾你。