什么时候for循环,.map()或.filter()有更好的性能?

时间:2018-05-16 19:04:30

标签: javascript

根据this问题,我们的想法是根据这些对象可能具有的某些属性值来查找对象数组中的对象,因此我使用此脚本来检查哪种方法更快:

const elementsInObject = 1000000;
const lengthOfItems = 5;

//just random text
function randomText() {
    var text = "";
    var possible = "abcdefghijklmnopqrstuvwxyz";

    for (var i = 0; i < lengthOfItems; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}


//ccreation of object
console.time("creatingObject");
var arrObj = [];
for (let i = 0; i < elementsInObject; i++) {
  let el = {
    prop1: randomText(),
    prop2: randomText(),
    types: [randomText(), randomText()]
  };

  arrObj.push(el);
}
console.timeEnd("creatingObject");


console.time("forFor");
var result = [];
for (let i = 0; i < arrObj.length; i++) {

     for(let q=0; q<arrObj[i].types.length; q++){

        if (arrObj[i].types[q] == "abcde") {
            result.push(arrObj[i]);
          }

     }

    }
console.timeEnd("forFor");

console.time("forIncludes");
var result = [];
for (let i = 0; i < arrObj.length; i++) {
  if (arrObj[i].types.includes("abcde")) {
    result.push(arrObj[i]);
  }
}
console.timeEnd("forIncludes");

console.time("filterIncludes");
var result = arrObj.filter(obj => {
  return obj.types.includes("abcde");
});
console.timeEnd("filterIncludes");

console.time("mapIncludes");
var result = [];
arrObj.map(obj => {
  if (obj.types.includes("abcde")) {
    result.push(obj);
  }
});
console.timeEnd("mapIncludes");

console.time("filterIndexOf");
var result = arrObj.filter(obj => {
  return obj.types.indexOf("abcde") > -1;
});
console.timeEnd("filterIndexOf");

我的想法是检查哪种方法更快更具可扩展性,我在这个例子中发现,for inside for是解决这个问题的最快算法(在节点和chrome中,而不是firefox)。所以问题是:当filter()或map()具有比?更好的性能时?

1 个答案:

答案 0 :(得分:1)

可能文件管理器是最好的,你的循环运行良好,因为你最终得到空数组,但如果不是这样你的循环正在执行推送操作。

包含可能会比indexOf略好,但不会明显。

在评论中你注意到你想要一个通用的方法来过滤,使用getter和比较器非常通用full example here

const elementsInObject = 5000000;

//random number between 1 and 11
function randomNum() {
  return Math.floor(Math.random()*100)+1
}

console.time("createObjectArray");
var arrObj = [...new Array(elementsInObject)].map(()=>({
  prop3: [randomNum(),randomNum()]
}));
console.timeEnd("createObjectArray");

const filterFn = getter => comparer => o =>
  comparer(getter(o));

//get a property
const getProp3 = o => o.prop3;
//you can write getB I'm sure

// compare contains
const contains = needle => haystack =>
  haystack.includes(needle);

// compare indexOf
const indexOf = needle => haystack =>
  haystack.indexOf(needle)>-1;

const filterProp3 = filterFn(getProp3);

console.time("filterContains");
arrObj.filter(
  filterProp3(contains(1))
);
console.timeEnd("filterContains");

console.time("filterIndexOf");
arrObj.filter(
  filterProp3(indexOf(1))
);
console.timeEnd("filterIndexOf");
console.log(
  "Items found:",
  arrObj.filter(
    filterProp3(contains(1))
  ).length
);