在JavaScript中使用break vs find()循环for循环

时间:2018-06-13 18:12:24

标签: javascript loops find break

刚看到有人写下这个:

let id = 1;
...
let employee = null;

for (const e of employees) {
    if (e.id === id) {
        employee = e;
        break;
    }
}

似乎是一种过于复杂的写作方式:

let id = 1;
...
let employee = employees.find(e => e.id === id);

使用breakfind()的循环有什么好处吗?

幕后的find()实施是什么?

6 个答案:

答案 0 :(得分:3)

性能比较

.find()for...break快。

检查this link以获取测试结果。 for...break.find()

慢30% 可以找到

.find()源代码here

IE11及以下版本的旧浏览器不支持

.find()。您需要使用polyfill。

意见

由于复杂程度和使用的内部算法,

.find()更好。使用for...break,您将始终进行线性搜索,这意味着n * n次重复。数组越大,功能越慢。

答案 1 :(得分:2)

可能是一样的。发现是更简洁和声明没有?

答案 2 :(得分:2)

试过这个:

var startTime, endTime;

function start() {
  startTime = new Date();
};

function end() {
  endTime = new Date();
  var timeDiff = endTime - startTime; //in ms
  console.log(timeDiff + " milliseconds");
}

let employees = [];
for (var i = 10000; i > 0; i--){
  let thisEmployee = {
    id: i,
    name: "Person" + i
  }
  employees.push(thisEmployee);
}

let id = 1;
let employee1 = null;
start();
for (const e of employees) {
    if (e.id === id) {
        employee1 = e;
        break;
    }
}
end();
console.log("Method1: ", JSON.stringify(employee1));
start();
let employee2 = employees.find(e => e.id === id);
end();
console.log("Method2: ", JSON.stringify(employee2));

第一种方法要慢得多:

"12 milliseconds"
"Method1: "
"{\"id\":1,\"name\":\"Person1\"}"
"0 milliseconds"
"Method2: "
"{\"id\":1,\"name\":\"Person1\"}"

答案 3 :(得分:2)

我将这两种方法都实现为具有相同签名(forBreakMethod(x)findMethod (x))的两种方法,并通过了简单的性能测试规范。

(() => {

const test = (DATA_LENGTH = 1000, INDEX = 9, TESTS_COUNT = 10000) => {
  // data initialization
  const employees = [];
  for (let i = 1; i <= DATA_LENGTH; i++){
    employees.push({ id: i });
  }
  
  // methods initialization
  const forBreakMethod = (x) => {
    const length = employees.length;
    for (let i = 0; i < length; i++) {
      if (x === employees.id) {
        return employees[i];
      }
    }
  }
  const findMethod = (x) => {
    return employees.find(item => x === item.id);
  }
  
  // for-break test
  const time1 = performance.now();
  for (let i = 0; i < TESTS_COUNT; i++) {
    forBreakMethod(INDEX);
  }
  const time2 = performance.now();
  console.log(`[for-break] find ${INDEX} from ${DATA_LENGTH}: ${time2 - time1}`);
  
  // find test
  const time3 = performance.now();
  for (let i = 0; i < TESTS_COUNT; i++) {
    findMethod(INDEX);
  }
  const time4 = performance.now();
  console.log(`[Array.find] find ${INDEX} from ${DATA_LENGTH}: ${time4 - time3}`);

  console.log('---------------');
};

test(10, 1, 1000000);
test(10, 5, 1000000);
test(10, 9, 1000000);
console.log('\n');
test(100, 10, 100000);
test(100, 50, 100000);
test(100, 99, 100000);
console.log('\n');
test(1000, 10, 10000);
test(1000, 500, 10000);
test(1000, 999, 10000);
console.log('\n');
test(10000, 10, 10000);
test(10000, 5000, 10000);
test(10000, 9999, 10000);

})();

我看到的结论是,如果我们要查找的项位于数据数组的左侧,则Array.find方法具有优势,但是当结果索引移至右侧时,其性能会降低。突破式方法似乎更稳定,因为它的性能不依赖于我们要查找的索引,但是其成本却很高。

非常粗糙,我想说,如果我们要遍历数据数组的前半部分,则可以将Array.find方法视为性能更高的方法,否则我将使用for-break方法。

PS Chrome,Safari,Firefox,2018年。

答案 4 :(得分:1)

很明显,本地find()函数比循环算法要快。但是,OP询问“使用循环是否有任何好处...?” 有人可能想循环的理论原因是,他们是否需要沿途处理不匹配的元素。

答案 5 :(得分:0)

所以我试过这个:

const array = [0, 1, 2, 3, 4, 5,];

for (const i of array) {
  console.log(i);
  if (i === 3)
    break;
}

array.find(i => {
  console.log(i);
  return i === 3;
});

两者都输出

0
1
2
3

所以,他们都会按照我的预期在他们找到的第一个答案上做短路,但就具体表现而言,我无法确定一个人是否比另一个好。我想如果不相同,表现将具有可比性 突出的一个重要区别是find返回值,但for循环必须处理循环中的值,否则将其分配给变量以便稍后使用。一个小细节,但它可能使查找代码的其他人更容易阅读。