Spread vs JSON.parse speed when calling simple function
const N = 100000;
function test(obj) {
var result = obj.a + obj.b;
return result;
}
function test2(obj) {
var result = obj.a + obj.b;
return result;
}
const objToCopy1 = { a: 1, b: 2 };
const objToCopy2 = { a: 1, b: 2 };
const objToCopy3 = { a: 1, b: 2 };
const objToCopy4 = { a: 1, b: 2 };
const objToCopy5 = { a: 1, b: 2 };
const startParse = Date.now();
for (let i = 0; i < N; ++i) {
test(JSON.parse(JSON.stringify(objToCopy1)));
test(JSON.parse(JSON.stringify(objToCopy2)));
test(JSON.parse(JSON.stringify(objToCopy3)));
test(JSON.parse(JSON.stringify(objToCopy4)));
test(JSON.parse(JSON.stringify(objToCopy5)));
}
console.log("test with PARSE:", Date.now() - startParse, "ms.");
const startSpread = Date.now();
for (let i = 0; i < N; ++i) {
test2({...objToCopy1});
test2({...objToCopy2});
test2({...objToCopy3});
test2({...objToCopy4});
test2({...objToCopy5});
}
console.log("test with spread:", Date.now() - startSpread, "ms.");
Result
test with PARSE: 263 ms.
test with spread: 12 ms.
When calling complex function (many operations inside):
const N = 10000;
function test(obj) {
let result = 0;
for (let i = 0; i < N; i++) {
result += obj.a + obj.b
}
return result;
}
function test2(obj) {
let result = 0;
for (let i = 0; i < N; i++) {
result += obj.a + obj.b
}
return result;
}
const objToCopy1 = { a: 1, b: 2 };
const objToCopy2 = { a: 1, b: 2 };
const objToCopy3 = { a: 1, b: 2 };
const objToCopy4 = { a: 1, b: 2 };
const objToCopy5 = { a: 1, b: 2 };
const startParse = Date.now();
for (let i = 0; i < N; ++i) {
test(JSON.parse(JSON.stringify(objToCopy1)));
test(JSON.parse(JSON.stringify(objToCopy2)));
test(JSON.parse(JSON.stringify(objToCopy3)));
test(JSON.parse(JSON.stringify(objToCopy4)));
test(JSON.parse(JSON.stringify(objToCopy5)));
}
console.log("test with PARSE:", Date.now() - startParse, "ms.");
const startSpread = Date.now();
for (let i = 0; i < N; ++i) {
test2({...objToCopy1});
test2({...objToCopy2});
test2({...objToCopy3});
test2({...objToCopy4});
test2({...objToCopy5});
}
console.log("test with spread:", Date.now() - startSpread, "ms.");
Result:
test with PARSE: 288 ms.
test with spread: 4054 ms.
Reason? Function deoptimisation when spreading objects:
// IC change with spread
ℹ 40% 4 P → P
ℹ 20% 2 . → 1
ℹ 20% 2 1 → P
ℹ 20% 2 P → N
// IC change with JSON.parse
100% 2 . → 1
i have a question why if
%HaveSameMap({...objToCopy1}, {...objToCopy2})
is true, test2 is deoptimized?