Хотел вам показать интересный пример, что иногда
JSON.parse(JSON.stringify(obj))работает быстрее, чем
{...obj}. Собираем простой тест с большим циклом, загоняем полученные клоны в параметры функции и готово:test(JSON.parse(JSON.stringify(objToCopy)))значительно быстрее, чем
test2({...objToCopy})Почему? кажется, что ответ на поверхности: запускаем Ноду с
--allow-natives-syntax и проверяем
const a = {a: 1};
const b = {...a};
%HaveSameMap(a, b); // false
const c = JSON.parse(JSON.stringify(a));
%HaveSameMap(a, c); // true
Дело раскрыто, функция стала мегаморфной, JIT вырубился, можно писать пост.
Но! Попробуем добавить вариант с
test3(structuredClone(objToCopy))
test with JSON.parse: 268 ms.
test with structuredClone: 308 ms.
test with spread: 2802 ms.
Проверяем:
const d = structuredClone(a);
%HaveSameMap(a, d); // false
Таааак
Что же получается. И
spread и structuredClone ведут к мегаморфности. Но при этом structuredClone не приводит к деоптимизациям. Дальше докидываю
Object.assign({}, objToCopy) и не смотря на мегаморфность
test with Object.assign: 238 ms.
Психую. Запускаю с
--trace_deopt и вижу, что спред постоянно вышибает (kind: deopt-eager, reason: wrong map)
Но почему Object.assign и structuredClone не приводят к деоптимизации?