对象键vs数组查找性能
Object key vs array lookup performance
示例1:
["member1", "member2",...,..., "member100000"]
示例2:
{
"member1": true, // (doesn't really need values, only keys :/)
"member2": true,
"...",
"member100000": true
}
我将成员存储在数组中,就像在示例1中一样,但是这样做,我必须在我的数组中迭代49999个项目,找到成员50000,所以我想简单地检查是否在javascript对象中定义了一个特定的键,这将是一个更好的方法,虽然我不需要存储一个值,但只检查键是否未定义?
我需要的是能够检查是否。"member50000"作为值存在于我的数组中,或者作为键存在于我的对象中。
我做了一些基准测试,但我不确定我是否得出了正确的结论,或者我在比较中是否做错了什么:http://jsperf.com/lolda123
根据上面的测试结果,是否可以公平地得出这样的结论:在一个值为布尔值(true)的对象中保存一个键/值对,并且执行if(obj["member50000"])
是性能最好的选项?即使不存在具有给定键的属性?正如我所看到的,根据我的测试结果,检查键本身是否存在,在性能方面似乎要昂贵得多,但检查键是否存在,确实是我所需要的。
我不关心值,所以我在这里遗漏了什么,或者为什么更好的解决方案似乎是通过键来查找值,而不是在对象内部查找键?
我也这么认为,使用Object会更快,但事实证明我错了!
我在NodeJS 6.3 (V8引擎)上使用与jsPerf相同的堆栈运行性能测试:
https://github.com/amoldavsky/js-array-indexof-vs-hashmap结果如下:
- 查找更大的数据集
- 创建对象数据结构(基本上是HashMap)是昂贵的!并且比使用数组 要慢得多
- 当组合插入和查找时,数组。indexOf要快得多
如果你认为我在任何测试中犯了错误,请随时提出,我们可以重新测试。虽然到目前为止看起来像数组。
obj.hasOwnProperty
比arr.indexOf
快得多http://jsperf.com/array-hasownproperty-vs-array-indexof
使用arr.indexOf
也应该比你做的任何循环都快。
我对此很好奇,因为Object.prototype
是任何数组实例的祖先,因此它一定比对象更笨重,并且在查找属性时速度更慢。
在我的测试中,我将字符串列表存储为数组元素和对象键。然后测量在对象和数组实现中检查每个键是否存在所花费的时间。重复10万次
一般来说,对象碰巧更快。Null对象在chromium上明显更快。
{
const iterations = 1000000;
let arrTotal = 0;
let objTotal = 0;
let nullObjTotal = 0;
let a = '';
let keys = [
"The standard Lorem Ipsum passage",
"used since the 1500sLorem ipsum dolor sit amet",
"consectetur adipiscing elit",
"Ut enim ad minim veniam",
"Excepteur sint occaecat cupidatat non proident",
"sunt in culpa qui officia deserunt mollit anim id est laborum",
"Section 1",
"32 of de Finibus Bonorum et Malorum",
"totam rem aperiam",
"Neque porro quisquam est",
"qui dolorem ipsum quia dolor sit amet",
"consectetur",
"adipisci velit",
"Ut enim ad minima veniam",
"the master-builder of human happiness",
"No one rejects",
"dislikes",
"or avoids pleasure itself",
"because it is pleasure",
"because it is pain",
"To take a trivial example",
"which of us ever undertakes laborious physical exercise",
"33 of de Finibus Bonorum et Malorum",
"similique sunt in culpa qui officia deserunt mollitia animi",
"id est laborum et dolorum fuga",
"Et harum quidem rerum facilis est et expedita distinctio",
"Nam libero tempore",
"omnis voluptas assumenda est",
"omnis dolor repellendus",
"Itaque earum rerum hic tenetur a sapiente delectus",
"1914 translation by H",
"RackhamOn the other hand",
"so blinded by desire",
"These cases are perfectly simple and easy to distinguish",
"In a free hour",
"every pleasure is to be welcomed and every pain avoided",
"or else he endures pains to avoid worse pains"
];
let nullObj = Object.create(null);
for (let key of keys) nullObj[key] = null;
let obj = {
"The standard Lorem Ipsum passage": null,
"used since the 1500sLorem ipsum dolor sit amet": null,
"consectetur adipiscing elit": null,
"Ut enim ad minim veniam": null,
"Excepteur sint occaecat cupidatat non proident": null,
"sunt in culpa qui officia deserunt mollit anim id est laborum": null,
"Section 1": null,
"32 of de Finibus Bonorum et Malorum": null,
"totam rem aperiam": null,
"Neque porro quisquam est": null,
"qui dolorem ipsum quia dolor sit amet": null,
"consectetur": null,
"adipisci velit": null,
"Ut enim ad minima veniam": null,
"the master-builder of human happiness": null,
"No one rejects": null,
"dislikes": null,
"or avoids pleasure itself": null,
"because it is pleasure": null,
"because it is pain": null,
"To take a trivial example": null,
"which of us ever undertakes laborious physical exercise": null,
"33 of de Finibus Bonorum et Malorum": null,
"similique sunt in culpa qui officia deserunt mollitia animi": null,
"id est laborum et dolorum fuga": null,
"Et harum quidem rerum facilis est et expedita distinctio": null,
"Nam libero tempore": null,
"omnis voluptas assumenda est": null,
"omnis dolor repellendus": null,
"Itaque earum rerum hic tenetur a sapiente delectus": null,
"1914 translation by H": null,
"RackhamOn the other hand": null,
"so blinded by desire": null,
"These cases are perfectly simple and easy to distinguish": null,
"In a free hour": null,
"every pleasure is to be welcomed and every pain avoided": null,
"or else he endures pains to avoid worse pains": null
};
let arr = [
"The standard Lorem Ipsum passage",
"used since the 1500sLorem ipsum dolor sit amet",
"consectetur adipiscing elit",
"Ut enim ad minim veniam",
"Excepteur sint occaecat cupidatat non proident",
"sunt in culpa qui officia deserunt mollit anim id est laborum",
"Section 1",
"32 of de Finibus Bonorum et Malorum",
"totam rem aperiam",
"Neque porro quisquam est",
"qui dolorem ipsum quia dolor sit amet",
"consectetur",
"adipisci velit",
"Ut enim ad minima veniam",
"the master-builder of human happiness",
"No one rejects",
"dislikes",
"or avoids pleasure itself",
"because it is pleasure",
"because it is pain",
"To take a trivial example",
"which of us ever undertakes laborious physical exercise",
"33 of de Finibus Bonorum et Malorum",
"similique sunt in culpa qui officia deserunt mollitia animi",
"id est laborum et dolorum fuga",
"Et harum quidem rerum facilis est et expedita distinctio",
"Nam libero tempore",
"omnis voluptas assumenda est",
"omnis dolor repellendus",
"Itaque earum rerum hic tenetur a sapiente delectus",
"1914 translation by H",
"RackhamOn the other hand",
"so blinded by desire",
"These cases are perfectly simple and easy to distinguish",
"In a free hour",
"every pleasure is to be welcomed and every pain avoided",
"or else he endures pains to avoid worse pains"
];
for (let i = 0, stamp = 0, length = keys.length; i < iterations; ++i) {
stamp = performance.now();
for (let j = 0; j < length; ++j) {
if (keys[j] in obj) a = keys[j];
}
objTotal += (performance.now() - stamp)/1000;
stamp = performance.now();
for (let j = 0; j < length; ++j) {
if (~arr.indexOf(keys[j])) a = keys[j];
}
arrTotal += (performance.now() - stamp)/1000;
stamp = performance.now();
for (let j = 0; j < length; ++j) {
if (keys[j] in nullObj) a = keys[j];
}
nullObjTotal += (performance.now() - stamp)/1000;
}
console.log(`Array total: ${arrTotal}; Array avarage: ${arrTotal/iterations}(s).`);
console.log(`Object total: ${objTotal}; Object avarage: ${objTotal/iterations}(s).`);
console.log(`Null object total: ${nullObjTotal}; Null object avarage: ${nullObjTotal/iterations}(s).`);
}
- 函数参数中的数据与指定变量之间的任何性能差异
- 提高JQuery的性能
- 正在全局范围中查找JavaScript函数
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 在不使用jquery的情况下查找页面中的所有锚点并附加函数
- es6 相当于下划线查找位置
- 在DOM中查找一个模式并替换它's的内容使用jquery
- 使用正则表达式评估电子邮件地址时出现性能问题
- React:按键的性能提升
- 如何使用jquery迭代具有相同属性的html元素并查找onclick事件
- 如何在不传递此信息的情况下查找被调用的元素
- 在Three.js中导出网格会提高性能吗
- Lodash 从值数组中查找数组中的值
- 如何使用JavaScript查找1和N之间的所有数字的总和
- Javascript对象中的跨浏览器密钥查找性能
- 提高字典查找大量数据的性能
- Javascript:作用域链/变量查找性能
- 在循环中缓存数组查找是否有任何性能提升
- 使用Javascript通过ID查找元素的最佳性能.数组或对象
- 对象键vs数组查找性能