Влияет ли оператор спреда на производительность? - PullRequest
1 голос
/ 25 апреля 2019

Ниже у меня есть 2 подхода для построения массива объектов.

Подход 1:

const employees = [
  {
    company: 'ABC',
    country: 'IN',
    zip: 123,
    employeeId: 123,
    employeeName: 'p'
  },
  {
    company: 'ABC',
    country: 'IN',
    zip: 123,
    employeeId: 456,
    employeeName: 'q'
  },
  {
    company: 'ABC',
    country: 'IN',
    zip: 123,
    employeeId: 789,
    employeeName: 'r'
  }
];

Подход 2 (использует оператор распространения):

const commonParams = {
  company: 'ABC',
  country: 'IN',
  zip: 123
};

const employees = [
  {
    ...commonParams,
    employeeId: 123,
    employeeName: 'p'
  },
  {
    ...commonParams,
    employeeId: 456,
    employeeName: 'q'
  },
  {
    ...commonParams,
    employeeId: 789,
    employeeName: 'r'
  }
]

Подход 2 имеет меньше строк кода, и добавление нового общего свойства к элементам массива будет намного проще.Но в случае большого объекта commonParams влияет ли подход 2 (с использованием оператора распространения) на производительность по сравнению с подходом 1?Будет ли оператор распространения распространяться по каждому из свойств в commonParams объекте для каждого из объектов в массиве employees?

Ответы [ 2 ]

3 голосов
/ 25 апреля 2019

Да, распространение переменной, которая ссылается на объект, на другой объект требует от интерпретатора поиска того, на что ссылается переменная, а затем поиска всех перечислимых собственных свойств (и связанных значений) объекта, который получает распространение, таккак вставить в новый объект.Это действительно требует бит вычислительной мощности.

Но на современных компьютерах и на современных движках JS требуемая вычислительная мощность практически отсутствует;какое это имеет значение, когда миллионы инструкций могут обрабатываться каждую секунду?Горстка пар ключ-значение не о чем беспокоиться.

Если вы не определили, что вы распространяете объект с тоннами пар ключ-значение, и это на самом деле вызывает узкое место в производительности, было бы лучше избегать преждевременной оптимизации и вместо этого стремиться писать чистый, читаемый код (который может часто вызывать использование распространенного синтаксиса).Для большого массива employees второй подход более читабелен, чем первый.

(хотя вы также можете рассмотреть возможность использования .map, чтобы сохранить код даже DRY-er:)

const employeesInitial = [
  {
    employeeId: 123,
    employeeName: 'p'
  },
  {
    employeeId: 456,
    employeeName: 'q'
  },
  {
    employeeId: 789,
    employeeName: 'r'
  }
];
const employees = employeesInitial.map((obj) => ({ ...obj, ...commonParams }));
1 голос
/ 25 апреля 2019

Время для запуска второго подхода будет больше (даже если на современных компьютерах очень мало), поскольку интерпретатор должен перебирать ключи commonParams и копировать их в каждый объект.

Написал тест, чтобы найти разницу, которая почти равна нулю для небольших объектов.

function runFirstApproach(){
  const employees1 = [
    {
      company: 'ABC',
      country: 'IN',
      zip: 123,
      employeeId: 123,
      employeeName: 'p'
    },
    {
      company: 'ABC',
      country: 'IN',
      zip: 123,
      employeeId: 456,
      employeeName: 'q'
    },
    {
      company: 'ABC',
      country: 'IN',
      zip: 123,
      employeeId: 789,
      employeeName: 'r'
    }
  ];
}

function runSecondApproach() {
  const commonParams = {
    company: 'ABC',
    country: 'IN',
    zip: 123
  };

  const employees2 = [
    {
      ...commonParams,
      employeeId: 123,
      employeeName: 'p'
    },
    {
      ...commonParams,
      employeeId: 456,
      employeeName: 'q'
    },
    {
      ...commonParams,
      employeeId: 789,
      employeeName: 'r'
    }
  ]
}

function runBenchmarkWithFirstApproach(){
  console.log("Avg time to run first approach -> ", getAvgRunTime(runFirstApproach, 100000))
}

function runBenchmarkWithSecondApproach(){
  console.log("Avg time to run second approach ->", getAvgRunTime(runSecondApproach, 100000))
}

function getAvgRunTime(func, rep){
  let totalTime = 0;
  let tempRep = rep;
  while(tempRep--) {
    const startTime = Date.now();
    func();
    const endTime = Date.now();
    const timeTaken = endTime-startTime;
    totalTime += timeTaken;
  }
  return totalTime/rep;
}

runBenchmarkWithFirstApproach();
runBenchmarkWithSecondApproach();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...