刚看到有人写下这个:
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);
使用break
与find()
的循环有什么好处吗?
幕后的find()
实施是什么?
答案 0 :(得分:3)
.find()
比for...break
快。
检查this link以获取测试结果。 for...break
比.find()
.find()
源代码here
.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循环必须处理循环中的值,否则将其分配给变量以便稍后使用。一个小细节,但它可能使查找代码的其他人更容易阅读。