This is the 4th day of my participation in the August More Text Challenge

Set

A Set object can store any type of data and can have only unique values.

Raw data types are compared by value, and objects are compared by reference.

Instance attributes

  • sizeRead-only property that returns the number of elements

methods

  • add(value)Add the element at the end
  • clear()Remove all elements
  • delete(value)Remove elements equal to this value
  • entries()Returns an iterator containing all elements in insertion order, with each iterator value being[value, value](To be consistent with Map)
  • forEach(callbackFn, thisArg)The callback method is called as an argument for each element in the insertion order
  • has(value)Returns whether the value is included
  • keys()values()Returns an iterator containing all elements in insertion order, with each iterator value beingvalue

Set VS Array performance comparison

The insert

Below 10 inserts, there is little difference, and even when using performance.now() to capture the running time, both are zero.

Set is 50% slower than Array, but the actual time difference is only 0.1ms, which is still very slight.

At 100,000, the gap continues to triple.

When we’re at 10 million, Set is 10 times longer than Array.

var s0 = new Set(a)var now = Date.now()
for(let i = 0; i<10000000; i++) {
    s0.add(i)
}
console.log(Date.now() - now);
Copy the code

The average time was 2289.8ms

var a0 = []
var now = Date.now()
for(let i = 0; i<100000000; i++) {
    a0.push(i)
}
console.log(Date.now() - now);
Copy the code

The average time was 194.2ms

And when I try to raise it again to 100 million, Set just gives me an error.

Uncaught RangeError: Value undefined out of range for undefined options property undefined
    at Set.add (<anonymous>)
    at <anonymous>:4:8
Copy the code

Cause analysis,

Because of Array’s push method, you just add elements to the end of the Array; Set, on the other hand, traverses the entire Set of values and compares them. If no identical values are found, the Set is added to the end. So the more Set elements that make up the Set, the longer it takes.

Query operation

Set queries are extremely fast, taking almost the same time no matter where the value is located. In contrast, the query time of an Array is highly dependent on the location of the value.

var s0 = new Set(a)for(let i = 0; i<10000000; i++) {
    s0.add(i)
}
var now = performance.now()
for(let i = 100; i<10000; i++) {
    s0.has(i)
}
console.log(performance.now() - now);
var now = performance.now()
for(let i = 100000; i<110000; i++) {
    s0.has(i)
}
console.log(performance.now() - now);
var now = performance.now()
for(let i = 5000000; i<5010000; i++) {
    s0.has(i)
}
console.log(performance.now() - now);
Copy the code

The average time was 2.5ms 2.8ms 2.1ms

var a0 = []
for(let i = 0; i<100000000; i++) {
    a0.push(i)
}
var now = performance.now()
for(let i = 100; i<10000; i++) {
    a0.includes(i)
}
console.log(performance.now() - now);
var now = performance.now()
for(let i = 100000; i<110000; i++) {
    a0.includes(i)
}
console.log(performance.now() - now);
var now = performance.now()
for(let i = 5000000; i<5010000; i++) {
    a0.includes(i)
}
console.log(performance.now() - now);
Copy the code

The average time was 66ms 1385ms 71728ms

Cause analysis,

Because Set is implemented using a hash table-like data structure; Array is a linked list, so elements need to be traversed. As a result, the more traversals are required, the longer the traversal takes.

Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structures used in this Set objects specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.

WeakSet

WeakSet objects can only store object data and can only have unique values.

An error is raised when you try to insert a non-object data type.

var s0 = new WeakSet([1])
// Uncaught TypeError: Invalid value used in weak set
// at WeakSet.add (
      
       )
      
// at new WeakSet (
      
       )
      
// at 
      
       :1:10
      

var s0 = new WeakSet()
s0.add('abc')
// Uncaught TypeError: Invalid value used in weak set
// at WeakSet.add (
      
       )
      
// at 
      
       :1:4
      
Copy the code

WeakSet vs Set difference

There are two main differences between the two:

  • WeakSet can only store objects, while Set can store arbitrary data types
  • WeakSet stores an object that will be garbage collected if there are no other references. This is the reason why WeakSet is called Weak, and it also means that WeakSet is not enumerable, so there is no size.

Try the following code in Chrome’s Developer Tools Console panel:

var a0 = []
for(let i = 0; i<10000000; i++) {
    a0.push(i)
}
var s0 = new WeakSet()
s0.add(a0)
a0 = null
console.log(s0)
// output: WeakSet {Array(10000000)}

// Click the "Collect Garbage" button in the Memory panel of Chrome Developer Tools to trigger GC

s0
// output: WeakSet {}
Copy the code

methods

Compared with Set, WeakSet has only the following three methods due to its weak reference characteristics:

  • add(value)Add the element at the end
  • delete(value)Remove elements equal to this value
  • has(value)Returns whether the value is included

compatibility

Finally, take a look at browser compatibility.

Set

WeakSet

Basically, most modern browsers support Set and WeakSet, and most use scenarios can be used safely.