Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用jQuery提高搜索JSON对象的性能_Javascript_Jquery_Json - Fatal编程技术网

Javascript 使用jQuery提高搜索JSON对象的性能

Javascript 使用jQuery提高搜索JSON对象的性能,javascript,jquery,json,Javascript,Jquery,Json,请原谅我,如果这个问题已经在某处得到了回答。我搜索过了,似乎这是一个相当具体的案例 下面是一个JSON示例(注意:这是一个非常精简的JSON,它是动态加载的,目前有126条记录): 我需要匹配正确的值组合。以下是我目前使用的函数: function drawOption(attid, optid) { var attlayout = layout[attid]; $.each(attlayout, function(k, v) { // d_opt_id and

请原谅我,如果这个问题已经在某处得到了回答。我搜索过了,似乎这是一个相当具体的案例

下面是一个JSON示例(注意:这是一个非常精简的JSON,它是动态加载的,目前有126条记录):

我需要匹配正确的值组合。以下是我目前使用的函数:

function drawOption(attid, optid) {
    var attlayout = layout[attid];
    $.each(attlayout, function(k, v) {
        // d_opt_id and d_opt_id are global scoped variable set elsewhere
        if (v.design_attribute_id == d_att_id
            && v.design_option_id == d_opt_id  
            && v.attribute_id == attid 
            && ((v.apply_to_options == 1 || (v.option_id === optid)))) {
                // Do stuff here
        }
    });
}
问题是我可能会迭代10-15个布局(唯一的attid),任何给定的布局(attid)可能有多达50种可能性,这意味着这个循环正在大量运行

考虑到必须匹配的多个条件,AJAX调用是否会更好?(这个JSON是通过PHP动态创建的,所以我可以设计一个PHP函数,可以更有效地实现这一点), 或者,我完全没有了解如何在JSON对象中查找项

一如既往,欢迎您提出任何改进代码的建议

编辑:

我很抱歉没有说清楚,但这个问题的目的是想找到一种改进性能的方法。这个页面有很多javascript,我知道在这个位置上性能比实际情况要低。

您考虑过使用jQuery grep函数吗


举个例子。

这里有一种技术,它可能会以使用更多内存为代价,产生更好的性能

我将留下简单的代码示例来说明这个概念

首先,您需要将JSON数据预处理到一些作为索引的附加数组中。以下是预处理后最终阵列的外观示例:

var layouts_by_attribute = {
    // attribute_id => array(layouts)
    2: [40, 41, 44],
    5: [326]
};

var layouts_by_design_attribute_id = {
    // design_attribute_id => array(layouts)
    4: [40, 41, 44, 326]
};
按属性查找布局现在非常快:

function findByAttribute(attribute_id) {
    return layouts = layouts_by_attribute[attribute_id];
}

function findByDesignAttribute(design_attribute_id) {
    return layouts = layouts_by_design_attribute[design_attribute_id];
}

我的第一个建议是停止使用
$。如果您想尽可能挤出每一点性能,请停止使用每一个
。比传统的循环做得多一点。查看浏览器的调试器是否正在运行(即Safari/Chrome的web开发工具),并逐步完成调试,直到jQuery完全返回执行

供参考,小提琴的代码为:

var myArr = [{"foo":"bar"},{"answer":42}];

debugger;

$.each(myArr, function(k, v) {
    console.log(k + ': ');
    console.dir(v);
});​
现在运行以下程序:

你会:

function foo(a, b) {
    var gA = globalA,
        gB = globalB;
    if (a === gA && b === gB) {
        // Do stuff
    }
}
至于基于对象成员的条件配对,我看不出还有什么可以改进的。您正在检查的对象属性是顶级的,并且您正在查看每个对象的本地实例(因此范围链查找很短)


如果我不知道这到底是怎么回事,这些就是我能提出的最好的建议。然而,我可以猜测,您从更简单的JSON数据开始的想法将是一个巨大的改进。如果您知道布局及其约束是什么,那么从服务器请求特定的详细信息将意味着您不必检查这么多条件。您可以简单地向服务器询问实际需要实现和循环的详细信息(以更新DOM或其他内容)。

首先,您应该测量,并且只有在存在真正的性能问题时才采取行动。你需要精确的数字,比如200毫秒或者80%的时间是在那里度过的。“它跑得很多”没有任何意义。浏览器可以快速循环

您可以像其他人提到的那样改进常量因子,比如使用本机for循环而不是jQuery.each。在这种情况下,更改全局变量不会对您有太大帮助

如果你真的想提高效率,你应该找到一个比O(n)更好的算法。假设您只使用这些数据来查找与特定条件匹配的元素,那么您可以使用JS对象作为散列来获得O(1)性能

仅举一个具体案例的示例:

var layout = {
  "2": { "2,,4,131,10,0": ["40", "93"], "2,115,4,131,0": ["41"] },
  "4": { ... },
  ...
};

在php中生成此输出相当容易,然后只需使用查找来查找与特定条件匹配的ID。

在尝试改进代码时,最好使用firebug评测来检查哪些函数需要时间。您可以通过单击firebug控制台面板中的profile按钮进行配置,然后运行代码或在代码中使用

从您给出的代码中,只能给出几个改进点

  • $。与本机循环解决方案相比,每个解决方案都很慢。最好 循环解决方案,看看这个
  • 最好将JSON更改为使用数组而不是对象文本。据说检索值的速度更快

  • 我以前对这样的问题有过经验,我的js对象数组由8000条记录和更多记录组成。 我的经验不是关于性能,而是关于代码的可读性、可维护性和可伸缩性

    因此,我在两年前开发了一个JS对象查询库:JSOQL

    它的工作原理类似于SQL,允许您使用类似于SQL的语法查询js对象数组

    示例用法是这样的,我记不清了,但是您可以在下载选项卡中下载示例用法

    new JSQOL().Select([field1, field2, field3 ...]).From({ ... }) .Where(fn) .Offset(int) .Limit(int) .Get();
    
    注: {…}是您的对象数组,或者它本身就是一个对象


    希望能有所帮助,如果您需要更多信息,可以给我发送消息。

    这不会在任何地方都起作用,但您的问题听起来是可以解决的


    如果没有webworkers,我会考虑的另一件事是尽量不要长时间阻塞ui。如果你能将它分为大约40毫秒,然后在几毫秒后设置下一个chunck超时,用户将有一个更愉快的体验。这需要一点修改,但是当某个东西花费的时间超过50到100毫秒时,用户就会开始注意到它 5个字段:v.design\u attribute\u id、v.design\u option\u id、v.attribute\u id、v.apply\u to\u options、v.option\u id

    您可以做的是向对象添加一个名为“key”的额外字段,该字段是这些字段中值的组合

    这里有一个例子

           {
                "key": "4_131_2_0_0" //i picked 0 to represent null, but you can pick any number                                    
                "id": "40",
                "attribute_id": "2",
                "option_id": null,
                "design_attribute_id": "4",
                "design_option_id": "131",
                "width": "10",
                "height": "10",
                "repeat": "0",
                "top": "0",
                "left": "0",
                "bottom": "0",
                "right": "0",
                "use_right": "0",
                "use_bottom": "0",
                "apply_to_options": "0"
            }
    
    但请注意,必须规范化每个值的长度。 M
    var layout = {
      "2": { "2,,4,131,10,0": ["40", "93"], "2,115,4,131,0": ["41"] },
      "4": { ... },
      ...
    };
    
    new JSQOL().Select([field1, field2, field3 ...]).From({ ... }) .Where(fn) .Offset(int) .Limit(int) .Get();
    
           {
                "key": "4_131_2_0_0" //i picked 0 to represent null, but you can pick any number                                    
                "id": "40",
                "attribute_id": "2",
                "option_id": null,
                "design_attribute_id": "4",
                "design_option_id": "131",
                "width": "10",
                "height": "10",
                "repeat": "0",
                "top": "0",
                "left": "0",
                "bottom": "0",
                "right": "0",
                "use_right": "0",
                "use_bottom": "0",
                "apply_to_options": "0"
            }
    
    function drawOption(attid, optid) {
        var attlayout = layout[attid];
        var needle = d_att_id + "_" + d_opt_id + "_" + attid + "_" + optid; //remember to normalize  length if you have to
    
        var idx = binarySearch(attlayout,needle);
    
        var item;
        if(idx !== -1){
            item = attlayout[idx];
            //do something 
    
        }
    }
    
     function drawOption(attid, optid) {
    
        var needle = attid + "_" + d_att_id + "_" + d_opt_id + "_" + attid + "_" + optid; //remember to normalize  length if you have to
    
        var item = layout[needle];
        if(typeof item !== "undefined"){
            //do something 
    
        }
    }
    
        var layout = {
        "2":[[...], ...],
        "5":[[...], ...]
        };
    
        var index = {};
    
        function makeKey(data) {
            return data.join('_');
        }
    
        for(var l in layout) {
            var cur = layout[l];
    
            for(var i in cur) {
                var item = cur[i];
                var key = makeKey([item.p1, item.p2, ...]);
    
                index[key] = index[key] || [];
                index[key].push(item);
            }
        }
    
        function find(attid, optid) {
            var key = makeKey([attid, optid, 1, d_att_id, ...]);
            return index[key]; //this is an array of results
        }