Тест производительности для оболочки функций по сравнению с вызовом конструктора и вызовом конструктора HaveSameMap

1

Я сделал некоторую оценку производительности с помощью CODE A и CODE B и хотел бы знать, почему именно V8 выдает так.

Код А

const makePoint = () => {
  class Point {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
  }

  return new Point(1, 2);
}

const a = makePoint();
const b = makePoint();

console.log(%HaveSameMap(a, b)); // false

Первый вопрос, почему в мире HasSameMap возвращает false. Я считаю, что и a, и b имеют одинаковую форму и проходят один и тот же процесс. Так почему они были бы разными?

Код B

class Point {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
 }
 var a = new Point();
 var b = new Point();

Второй вопрос. Сравнение времени выполнения этих данных имеет существенный разброс. Я просто хочу понять базовые системы типов V8. Почему это так. Вызов new Point() против ее возврата внутрь функции makePoint(). Что здесь происходит?

Обновление - МЕТОДИКА ИСПЫТАНИЙ

Я тестирую то же самое через внешний пакет

и мой тестовый код выглядит так:

const { performance } = require('perf_hooks');

performance.mark('start');

while (iterations--) {
  makePoint();
}

performance.mark('end');

performance.measure('My Special Benchmark', 'start', 'end');
  • 0
    Как вы тестируете производительность? Вы повторяете тесты несколько сотен или тысяч раз, чтобы получить среднее значение? Вы запускали один перед другим, но в том же файле кода - JIT мог изменить ваши значения. Пожалуйста, опишите вашу методологию тестирования производительности.
  • 0
    Я думаю, что 2 вопроса должны быть отделены от вопросов переполнения стека, а не связаны между собой.
Показать ещё 3 комментария
Теги:
performance
performance-testing
v8

2 ответа

1
Лучший ответ

В вашем первом фрагменте вы создавали не только экземпляр в makePoint но и сам class Point. Каждый раз, когда вы makePoint(), вы создаете новый класс:

console.log(makePoint().constructor === makePoint().constructor) // false

Я думаю, вы ищете

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
const makePoint = () => new Point(1, 2);
const a = makePoint();
const b = makePoint();

console.log(%HaveSameMap(a, b)); // true
console.log(a.constructor == b.constructor, a.constructor == Point); // true, true
  • 0
    Это то, что я искал.
  • 0
    Можете ли вы также посмотреть на этот мой вопрос - stackoverflow.com/questions/51609846/…
3

Вы создаете новый класс Point при каждом вызове makePoint. Это может стать немного более очевидным, когда вы сразу возвращаете класс:

const makePoint = (x, y) => {
  class Point {...};
  return Point;
}

Класс создается каждый раз, когда оценивается литерал класса. Вы можете увидеть, как это происходит при добавлении console.log прямо перед определением класса. В вашем случае это оценивается каждый раз.

Точно так же создание нового класса каждый раз более дорогостоящее, чем просто повторное использование одного и того же класса. V8 должен создать множество внутренних структур данных для поддержки быстрого создания экземпляра. Использование класса за один раз поражает этот очень распространенный шаг, который является замедление, которое вы видите.

  • 0
    Это замечательное объяснение, но опять-таки было больше смущено из-за Shape / Hashmaps. Ты определенно прояснил мой второй пункт лучше. Добавили +1.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню