缓存"深度"使用GUID作为键的JSON对象

时间:2014-09-18 16:30:32

标签: javascript json caching recursion large-data

所以我有一个大而简单的对象,它是从我的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的变量,其中可能存在数十万个属性。

这有助于或阻碍这种情况吗?

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

2 个答案:

答案 0 :(得分:1)

你做出了正确的选择。

对象引用相当小。即使有数千个对象,这样的对象(内部存储为类似数组的哈希映射)也不应该显着增加内存使用 - 最多几MB。创建缓存时,您不会复制对象。您将指针放入对象(数组样式)中,该对象指向您已反序列化的结构中的对象。所以你没有制作所有数据的第二份副本。只是GUID和指针的缓存。

此缓存方法使用JavaScript的一个很棒的功能,即属性索引在内部保持排序。然后通过二分搜索执行属性索引(例如,cache[guid])的查找。这将比未循环数据的循环或递归搜索快几个数量级。

答案 1 :(得分:1)

  

然而,这实际上最终会导致性能提升

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

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

  

或者这可能导致记忆问题吗?

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