This is the second day of my participation in the August More text Challenge. For details, see: August More Text Challenge
background
Today, I found that Map performs better than Object when frequently manipulating key-value pairs. I simply tested the difference between the two.
conclusion
First the conclusion:
The performance difference between
- When the key is an ordered integer, Object performs better than Map. (V8 optimizes Object when the key is an ordered consecutive positive integer)
- When the key is a string, a non-sequential integer, or a Symbol, Map adds and reads better than Object, and the performance of modification and deletion is similar. (Object converts the key to String, which consumes performance)
- If key is of another data type, only Map can be selected. (The key of Object can only be string or symbol)
The other difference
- Object can be used in a variety of ways
(literals, new Object(), object.create (), etc.)
Create the literal in a convenient and quick way. A Map can only be created using the constructor;- The Map itself has a size attribute, and the Object needs to be obtained using methods such as keys(), values(), etc.
- Map itself has an iterable property, Object does not.
- Map maintains insertion order, Object does not.
process
Let’s take a look at how the test works. Let’s test the difference when the key is a String
function createRandomKey() {
return new Date().getTime().toString().substr(6.7) + The '-' + (Math.random() * 100000000).toString().substr(0.7);
}
let keys = []
function setKeys() {
for (let i = 0; i < 1000000; i++) {
keys.push(createRandomKey())
}
}
setKeys()
let obj = new Object(a)let map = new Map(a)function getObjectTimeDiff() {
let t1 = new Date().getTime()
for (let i in keys) {
obj[keys[i]] = i
}
let t2 = new Date().getTime()
for (let j in keys) {
let value = obj[keys[j]]
}
let t3 = new Date().getTime()
for (let k in keys) {
obj[keys[k]] = keys[k]
}
let t4 = new Date().getTime()
for (let l in keys) {
delete obj[keys[l]]
}
let t5 = new Date().getTime()
return ` object to add:${t2 - t1}, read:${t3 - t2}To:${t4 - t3}To delete:${t5 - t4}`
}
function getMapTimeDiff() {
let t1 = new Date().getTime()
for (let i in keys) {
map.set(keys[i], i)
}
let t2 = new Date().getTime()
for (let j in keys) {
let value = map.get(keys[j])
}
let t3 = new Date().getTime()
for (let k in keys) {
map.set(keys[k], keys[k])
}
let t4 = new Date().getTime()
for (let l in keys) {
map.delete(keys[l])
}
let t5 = new Date().getTime()
return ` map to add:${t2 - t1}, read:${t3 - t2}To:${t4 - t3}To delete:${t5 - t4}`
}
console.log(getObjectTimeDiff())
console.log(getMapTimeDiff())
Copy the code
If we execute this multiple times, we will get something like this (depending on the execution environment). It is clear that Map takes less time to add and read keys than Object
The first time an object increment is executed:1121, read:710To:339To delete:397The map to add:545, read:220To:453To delete:491The second execution of object increment:1145, read:702To:330To delete:396The map to add:542, read:241To:468To delete:510The third time we add object:1153, read:707To:359To delete:403The map to add:546, read:237To:465To delete:507The fourth time to add object:1138, read:697To:333To delete:387The map to add:542, read:248To:451To delete:444.Copy the code
Modify the code to change keys to a set of subscripts to test when keys are consecutive integers
function setKeys() {
for (let i = 0; i < 1000000; i++) {
keys.push(i)
}
}
Copy the code
Many times to perform
The first time an object increment is executed:256, read:140To:134To delete:234The map to add:419, read:192To:294To delete:432The second execution of object increment:234, read:137To:136To delete:232The map to add:412, read:186To:283To delete:425The third time we add object:254, read:139To:130To delete:227The map to add:411, read:181To:296To delete:430The fourth time to add object:262, read:140To:135To delete:241The map to add:421, read:205To:309To delete:459.Copy the code
As you can see, Object performs better than Map when consecutive integers are used as keys