简体   繁体   English

对象键与数组查找性能

[英]Object key vs array lookup performance

Example 1:示例 1:

["member1", "member2",...,..., "member100000"]

Example 2:示例 2:

{
    "member1": true, // (doesn't really need values, only keys :/)
    "member2": true,
    "...",
    "member100000": true
}

I'm storing members in an array on each piece of content like in Example 1, but doing it like this I'd have to iterate through 49999 items in my the array, to find member 50000, so I was thinking simply checking if a specific key is defined within the javascript object would be a better approach here, although I do not need to store a value, but only check whether the key is undefined or not?我将成员存储在每个内容的数组中,就像示例 1 一样,但是这样做我必须遍历数组中的 49999 个项目,才能找到成员 50000,所以我想简单地检查一下在 javascript 对象中定义特定的键在这里是一个更好的方法,虽然我不需要存储值,但只检查键是否未定义?

What I need is to be able to check if eg.我需要的是能够检查例如。 "member50000" exists as a value within my array - or as a key inside my object. “member50000”作为数组中的值存在 - 或作为对象中的键存在。

I did some benchmarking tests, but I'm not sure I've come to the right conclusion, or if I'm doing something wrong in my comparison: http://jsperf.com/lolda123我做了一些基准测试,但我不确定我得出了正确的结论,或者我在比较中做错了什么: http : //jsperf.com/lolda123

According to the above test results, would it then be fair to conclude that saving a key/value pair within an object where the value is boolean (true), and doing if(obj["member50000"]) is the best performing option?根据上述测试结果,是否可以得出将键/值对保存在值为布尔值 (true) 的对象中并执行if(obj["member50000"])是性能最佳选项的结论是否公平? Even if no property with the given key even exists?即使不存在具有给定键的属性? As I see it, according to my test results, checking for the existence of the key itself, would seem much more expensive in terms of performance, but checking if the key is there, really is all I need.正如我所看到的,根据我的测试结果,检查密钥本身是否存在,在性能方面似乎要昂贵得多,但检查密钥是否存在,确实是我所需要的。

I don't care about the value, so am I missing something here, or why would the better solution seem like being the one where you look up the value, by the key, instead of just looking up the key, inside the object?我不在乎价值,所以我在这里遗漏了什么,或者为什么更好的解决方案似乎是你通过键查找值的方法,而不是仅仅在对象内部查找键?

Well I thought the same thing, that using an Object will be faster, and I proved myself wrong!好吧,我认为同样的事情,使用 Object 会更快,我证明自己错了!

I ran the performance tests using the same stack as jsPerf on NodeJS 6.3 ( V8 engine ):我在 NodeJS 6.3(V8 引擎)上使用与 jsPerf 相同的堆栈运行性能测试:

https://github.com/amoldavsky/js-array-indexof-vs-hashmap https://github.com/amoldavsky/js-array-indexof-vs-hashmap

The results are:结果是:

  • lookup is much faster on larger data sets在较大的数据集上查找要快得多
  • creating the Object datastructure ( basically a HashMap ) is EXPENSIVE!创建对象数据结构(基本上是 HashMap )是昂贵的! and much slower than using an array并且比使用数组慢得多
  • when combined insert and lookup, array.indexOf is faster by a very big margin当结合插入和查找时,array.indexOf 的速度要快得多

If you believe I made a mistake in any of my tests feel free to bring it up and we can retest.如果您认为我在任何测试中犯了错误,请随时提出来,我们可以重新测试。 Though so far looks like array.indexOf is much faster.虽然到目前为止看起来 array.indexOf 快得多。

obj.hasOwnProperty is much faster than arr.indexOf http://jsperf.com/array-hasownproperty-vs-array-indexof obj.hasOwnPropertyarr.indexOf http://jsperf.com/array-hasownproperty-vs-array-indexof快得多

Using arr.indexOf should also be faster than any looping you do.使用arr.indexOf也应该比任何循环都要快。

Was curious about this since Object.prototype is an ancestor of any array instance, therefore it must be bulkier than an object and slower when it comes to property lookup.对此很好奇,因为Object.prototype是任何数组实例的祖先,因此它必须比对象更大,并且在属性查找方面更慢。

In my test I store a list of strings as array elements and an object keys.在我的测试中,我将字符串列表存储为数组元素和对象键。 Then I measure how much time it takes to check for existance of each key in both object and array implementations.然后我测量检查对象和数组实现中每个键是否存在所需的时间。 Repeat 100000 times.重复 100000 次。

Generally, objects happen to be faster.通常,对象碰巧更快。 Null objects are significantly faster on chromium. 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).`);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM