缓存一个“;深“;使用GUID作为键的JSON对象

Caching a "deep" JSON object using GUIDs as keys

本文关键字:对象 JSON GUID 缓存 一个 使用      更新时间:2023-09-26

所以我有一个大而简单的对象,它是从JavaScript应用程序中的JSON文件加载的。

这个文件有大约9 MB的数据(不过缩小后应该会更低),是一个嵌套结构,如下所示:

{
    "guid": "guid 1 here",
    "children": [
        {
            "guid": "guid 2 here",
            "other": "properties",
            "here": true,
            "children": [
                {
                    "guid": "guid 3 here",
                    ...
                },
                ...
            ]
        },
        ...
    ]
}

我不知道这个对象的深度,我需要使用一个通用函数来根据节点的GUID属性定位节点,而不管它在树中的深度如何。这个递归函数(我知道可以使用while循环而不是递归来优化它,但无论如何它都很昂贵)很慢。

我想知道最初加载这个对象后,我是否创建了一个类似这样的缓存结构:

var cache = {
    "guid 1 here": [reference to object],
    "guid 2 here": [reference to object],
    "guid 3 here": [reference to object]
};

我认为,这将使寻找物体更快,因为我可以说

var node = cache[guid];

然而,这最终会提高性能吗?还是可能会导致内存问题?我从未处理过像cache这样的变量,其中可能有数十万个属性。

这会帮助还是阻碍这种情况?

一如既往地感谢你的建议,所以,你们太棒了。

您做出了正确的选择。

对象引用相对较小。即使有数千个对象,这样的对象(内部存储为类似数组的哈希图)也不应该显著增加内存使用量——最多几MB。当您创建缓存时,您并不是在复制对象。您正在将指针放入对象(数组样式)中,该指针指向反序列化结构中的对象。因此,您不会对所有数据进行第二次复制。只是GUID和指针的缓存。

这种缓存方法使用了JavaScript的一个伟大特性,即属性索引在内部保持排序。然后通过二进制搜索执行按属性索引(例如cache[guid])的查找。这将比对未排序数据进行循环或递归搜索快几个数量级。

然而,这真的会成为性能的提升吗

可能吧。拥有一个大型的恒定访问数据结构(即使构建成本很高)通常比重复迭代所有"数十万"节点更快。

但是,如果您可以优化递归查找函数,例如通过从guid派生父节点的位置,这可能不会有那么大的好处。

或者这可能会导致内存问题?

是的,在内存不足的设备上,大型数据结构总是会导致内存问题。但是,如果您对原始JSON数据没有任何问题,那么这应该不是问题。