2016-07-05 88 views
0

我有一个函数,它包含一些嵌套for循环并按预期工作。JavaScript嵌套循环使函数执行速度太慢

问题但是,它必须通过大量数据的循环,这意味着时间过久执行,往往同时执行冻结浏览器。

从服务器获取的数据大约为2000+个元素。

任何人都可以提出一个更有效的方式来编写这个函数,这将减少迭代的次数,并加快过程?

function markers(boxes) { 
 
    $.getJSON('empdata.json', function (data) { 
 

 
      var json = data; 
 
      for (var i = 0; i < boxes.length; i++) { 
 

 
       for(var v = 0; v < json.length; v++) { 
 

 
        //loop through parsed markers within bounds 
 
        var obj = json[v]; 
 
        if (boxes[i].contains(new google.maps.LatLng(obj.latitude, obj.longitude))) { 
 
        var marker = new google.maps.Marker({ 
 
         position: new google.maps.LatLng(obj.latitude, obj.longitude), 
 
         map: map, 
 
        }); 
 

 
        } else { 
 
         console.log("out of box"); 
 
        } 
 
       } //close bounds markers 
 

 
      } //close full loop parse 
 
    }) 
 
};

的功能的第一部分简单地获得关于从使用jQuery $.GetJSON功能的静态JSON文件映射位置的数据。

第二部分根据给定的参数循环遍历已创建的边界框。最后,第三部分循环遍历JSON文件中的每个项目,并在给定边界内创建地图引脚。

我认为问题是可以循环很多框,并且这个乘以JSON文件中的2000多个项目意味着函数每次都必须经过数千次迭代。

+2

如果问题的目标是获得优化/改进和现有的代码工作正常,你应该穿上[CodeReviews(HTTP问题://codereview.stackexchange。 COM /)。此外,对于代码冻结浏览器,你可以看看网络工作者,服务人员 – Rajesh

+0

有数据结构可以帮助,但它是一个很大的话题。一种方法是将你的“盒子”分为象限,子象限和次象限等,这样你可以大大减少对象到盒子的比较次数。 – Pointy

+0

尽管之前的评论是好的,应该考虑在我看来,这里的一个非常重要的一点也是从浏览器中拿走计算负载,即使用异步调用来让迭代由后端完成,并且因此确保不会使前端过载。然后,您可以使用提供的回调函数计算的数据,并且不会有任何浏览器冻结。 (这当然不会增加计算/迭代速度,但恕我直言在这种情况下仍然是一个重要的事情)。 –

回答

0

嗨我不知道这是否会有任何帮助,但如何理解它的功能必须通过一个大数据库,因为它的缓慢。

所以它将是一个很好的解决方案来划分您的数据库,所以添加一个通用参数,可以将您的巨大数据库分成4-8个较小的数据库,并确保它会一个接一个地通过它们,或者立即到达一个它就像我说说不上去

如果要去的任何帮助

+0

因此,如果我理解正确,您希望OP加载部分数据。更小的块和附加它,更像FB上的饲料。我对吗? – Rajesh

+0

是的,所以浏览器不会扼杀一大块数据 – Jairzinho

+0

而不是削减数据库OP可以简单地查询索引。 O(2K)不是庞大的数据。 – morels

2

瓶颈在你的代码是不是嵌套循环本身,而是它的谷歌标志印刷,这是非常非常慢。

但是你可以做一些事情,如:

  • 避免像var obj = json[v];临时变量的娱乐,因为它创造了很多的开销。重新分配该变量会更好。 (这一原则也为喜欢Phaser.io快速JS游戏库的基础同样的情况为:

    • for (var i = 0 ...
    • for(var v = 0 ...
    • var marker = new google.maps.Marker({ ...
  • new google.maps.LatLng(obj.latitude, obj.longitude)创建避免召回新对象比分配更昂贵。

  • 你可以用fusion tables
  • 更换标志的创建做出标记稀释剂尽可能
  • 使用DOM DocumentFragments(如果你看到here打印几乎是瞬间)
  • 没有控制台登录,因为它实在是太慢了!更好地将文本附加到作为页面日志的DOM div上。
  • 去异步!尝试将单个标记的打印委托给异步回调,以避免花费等待标记创建结束的时间。
  • boxes[i].contains()是什么复杂性?看看它在内部循环中,所以它运行N * M次,其中N是boxes的长度,M是json的长度。在计算理论中,这个函数的优化越多,整个剪切运行得越快。

编辑:

发现了一个有趣的是quick script同步基准测试2K标记生成VS异步之一。进行异步时,我的电脑使用时间减少了大约22倍。

核心功能是:

var createmarker=function(coordinates,index) { 
    setTimeout(function() { 
    var neighborMarker = new google.maps.Marker({ 
     position: coordinates, 
     map: map, 
     title:'Marker '+index, 
     icon: 'https://cloud.githubusercontent.com/assets/238439/4837489/46de6daa-5fd7-11e4-9622-0e1cc674f6b2.png' 
    }); 

    markersArray.push(neighborMarker); 
    },10); 
}; 

clearMarkers('Asynchronous',function(coordsArray,timeini) { 
    for(var index=0;index<coordsArray.length;index++) { 
    createmarker(coordsArray[index], index); 
    } 
});