Underscore.js性能问题 - 我可以使用_.defer

时间:2013-04-24 05:43:02

标签: javascript jquery performance foreach underscore.js

在我使用underscore.js和jquery构建的简单Web应用程序中。对于所有人(js对象)的列表,我将过滤掉他们访问过的所有地点(js对象)的列表。人员列表是一个html表格,其中td具有地点图像图标,点击该图标会显示他们访问过的所有地点的列表。 图标只能显示在至少一个地方访问过的人。这里的问题是人数和地点数量来自2000100。因此,下面的代码执行2000*100组合。浏览器抱怨我没有反应的脚本。代码如下:

_.each(peopleList, function (person, index, list) {

    //filter the respective places for people
    var visitedPlaces = _.filter(places, function (place) {
        return place.PeopleId == person.Id;
    });

    if (_.isEmpty(visitedPlaces)) {
        $("a#" + place.PeopleId).remove();
    }
});

死亡简单不是吗。对于每个人,检查访问过的地点是否跟踪了他。如何优化上述代码以解除阻塞和响应。尝试在某些地方放入_.defer_.delay,但没有改善

3 个答案:

答案 0 :(得分:2)

FWIW,这是我用下划线解决它的方法。

function removeNonTravelers(people, visits) {
    var travelers    = _.pluck(visits, 'PeopleId'),
        nonTravelers = _.reject(people, function (person) {
            return _.contains(travelers, person.Id);
        });

    $(_.map(nonTravelers, document.getElementById)).remove();
}

http://jsfiddle.net/FWzeN/

答案 1 :(得分:1)

我的建议是删除下划线并使用普通的JS:

function removeNonTravelers(people, visits) {
    var i, peopleId,
        numPeople = people.length,
        numVisits = visits.length,
        index = {}, nonTravelers = [];

    // index
    for (i = 0; i < numVisits; i++) {
        peopleId = visits[i].PeopleId;

        if (!index.hasOwnProperty(peopleId)) {
            index[peopleId] = 1;
        } else {
            index[peopleId]++;
        }
    }

    // find HTML elements to remove
    for (i = 0; i < numPeople; i++) {
        peopleId = people[i].Id;

        if (!index.hasOwnProperty(peopleId)) {
            nonTravelers.push(document.getElementById(peopleId));
        }
    }

    // remove them all at once
    $(nonTravelers).remove();
}

这个速度相当快。如果我没有犯任何错误,你的测试用例(2000人,100个地方)在我过时的笔记本电脑上超过700次操作(不包括DOM操作)。

亲自尝试:http://jsperf.com/where-not-exists-in-javascript

答案 2 :(得分:0)

var hashMap = {};

_.each(places, function(place) {
  hashMap[place.PeopleId] = place;
});

_.each(peopleList, function (person, index, list) {

    //filter the respective project documents
    var visitedPlaces = hashMap[person.id];

    if (visitedPlaces) {
        $("a#" + place.PeopleId).remove();
    }
});