Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Spread VS JSON.parse performance in function optimisation

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.