Skip to content

Instantly share code, notes, and snippets.

@omar-azmi
Created September 12, 2023 14:10
Show Gist options
  • Select an option

  • Save omar-azmi/1662b631718779f780fe87fa8ca7f518 to your computer and use it in GitHub Desktop.

Select an option

Save omar-azmi/1662b631718779f780fe87fa8ca7f518 to your computer and use it in GitHub Desktop.
structuredClone vs Object cloning for `map: Map<number, Set<number>>`, where `map.size` is about 500 and `map.get(any).size` averages to about 10
const array_from = Array.from
const math_random = Math.random
const mapToObject = <MK extends PropertyKey, MV>(map: Map<MK, Iterable<MV>>): Record<MK, Array<MV>> => {
const obj = {} as Record<MK, Array<MV>>
map.forEach((value, key) => {
obj[key] = array_from(value)
})
return obj
}
const randInt = (min: number, max: number) => ((math_random() * (max - min) + min) | 0)
const map_obj: Map<number, Set<number>> = new Map()
const add_random_entry = () => {
map_obj.set(randInt(0, 2000), new Set(
Array<number>(randInt(0, 20)).fill(0).map(
() => randInt(-500, 500)
)
))
}
for (let i = 0; i < 500; i++) { add_random_entry() }
// test mapToObject
let obj, end, start = performance.now()
for (let i = 0; i < 500; i++) {
obj = mapToObject(map_obj)
obj[12] ? (obj[12][0] += 1) : delete obj[12] // ensure that jit does not simply jump to disposing of obj
}
end = performance.now()
console.log("objectClone: ", end - start, " ms for 500 runs")
// test structuredClone
let map_cloned
start = performance.now()
for (let i = 0; i < 500; i++) {
map_cloned = structuredClone(map_obj)
map_cloned.get(12) ? (map_cloned.get(12)!.add(-1)) : (map_cloned.set(12, new Set([5, 5, 5]))) // ensure that jit does not simply jump to disposing of map_cloned
}
end = performance.now()
console.log("structuredClone: ", end - start, " ms for 500 runs")
/** results on V8 Chromium (Edge v116)
* objectClone: 303.80000019073486 ms for 500 runs
* structuredClone: 642.9000000953674 ms for 500 runs
*/
@omar-azmi
Copy link
Author

compiled minified js:

const d=Array.from,f=Math.random,p=e=>{const r={};return e.forEach((s,l)=>{r[l]=d(s)}),r},a=(e,r)=>f()*(r-e)+e|0,c=new Map,u=()=>{c.set(a(0,2e3),new Set(Array(a(0,20)).fill(0).map(()=>a(-500,500))))};for(let e=0;e<500;e++)u();let o,t,m=performance.now();for(let e=0;e<500;e++)o=p(c),o[12]?o[12][0]+=1:delete o[12];t=performance.now();console.log("objectClone: ",t-m," ms for 500 runs");let n;m=performance.now();for(let e=0;e<500;e++)n=structuredClone(c),n.get(12)?n.get(12).add(-1):n.set(12,new Set([5,5,5]));t=performance.now();console.log("structuredClone: ",t-m," ms for 500 runs");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment