← Назад к вопросам

Валидно ли высчитывать производительность участка кода с использованием Date.now

2.2 Middle🔥 101 комментариев
#Оптимизация и производительность#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Измерение производительности с помощью Date.now()

Измерение производительности участка кода с использованием Date.now() возможно, но это не лучший способ. Date.now() имеет значительные ограничения, которые могут привести к неточным результатам. Для серьезного измерения производительности есть лучшие инструменты.

Date.now() — базовый способ

Date.now() возвращает количество миллисекунд с 1970 года (Unix timestamp). Это самый простой способ, но с оговорками.

const start = Date.now()

// Выполняем операцию
for (let i = 0; i < 1000000; i++) {
  Math.sqrt(i)
}

const end = Date.now()
const duration = end - start

console.log(`Время выполнения: ${duration}ms`) // "Время выполнения: 5ms"

Проблемы с Date.now()

1. Низкая точность (1 миллисекунда)

Date.now() дает точность только до миллисекунд. Если операция выполняется быстрее, результат будет неточным или вообще 0.

// Проблема: слишком быстрая операция
const start = Date.now()

const arr = [1, 2, 3]
const result = arr.find(x => x === 2) // Очень быстро!

const end = Date.now()
console.log(end - start) // Возможно, 0ms (неточно!)

2. Влияние других процессов

ОС и другие процессы могут влиять на результат. Тест может пройти быстро или медленно в зависимости от нагрузки на систему.

const start = Date.now()
while (Date.now() - start < 10) {
  // Ждем 10ms
}
console.log(Date.now() - start) // Может быть 10-50ms (не точно)

3. Невозможность отделить вашу операцию от шума

Есть "шум" — JavaScript двигатель работает параллельно (garbage collection, компиляция JIT и т.д.), что влияет на результат.

const times = []

for (let i = 0; i < 5; i++) {
  const start = Date.now()
  performWork()
  const end = Date.now()
  times.push(end - start)
}

console.log(times) // [5, 4, 15, 5, 6] — разброс большой!

Performance.now() — лучший способ

Performance.now() — это более точный API для измерения времени. Дает точность до микросекунд (0.001 ms).

Преимущества:

  • Точность до микросекунд
  • Не влияет смена системных часов
  • Специально разработан для измерения производительности
  • Работает в браузерах и Node.js (18+)
const start = performance.now()

// Выполняем операцию
for (let i = 0; i < 1000000; i++) {
  Math.sqrt(i)
}

const end = performance.now()
const duration = end - start

console.log(`Время выполнения: ${duration.toFixed(3)}ms`) // "Время выполнения: 5.237ms"

Пример с более точными результатами:

// Проблема Date.now()
const start1 = Date.now()
const arr = Array.from({ length: 100 }, (_, i) => i)
const result = arr.find(x => x === 50)
const end1 = Date.now()
console.log(`Date.now(): ${end1 - start1}ms`) // Обычно 0ms

// Решение Performance.now()
const start2 = performance.now()
const arr2 = Array.from({ length: 100 }, (_, i) => i)
const result2 = arr2.find(x => x === 50)
const end2 = performance.now()
console.log(`performance.now(): ${(end2 - start2).toFixed(3)}ms`) // 0.123ms

Performance.mark() и Performance.measure()

Для более сложного профилирования используй Performance API с marks и measures:

// Отметить начало
performance.mark("operation-start")

// Выполнить операцию
for (let i = 0; i < 1000000; i++) {
  Math.sqrt(i)
}

// Отметить конец
performance.mark("operation-end")

// Измерить разницу
performance.measure("operation", "operation-start", "operation-end")

// Получить результат
const measure = performance.getEntriesByName("operation")[0]
console.log(`Измеренное время: ${measure.duration.toFixed(3)}ms`)

Преимущества этого способа:

  • Отделяет измерения от кода
  • Можно получить результат позже
  • Встроенная интеграция с DevTools
  • Полезно для сложных сценариев

Console.time() — удобный способ

Для быстрого профилирования в разработке используй console.time():

console.time("sort")

const arr = Array.from({ length: 10000 }, () => Math.random())
arr.sort((a, b) => a - b)

console.timeEnd("sort")
// Вывод: sort: 2.456ms

Это использует Performance API под капотом и удобно для разработки.

Правильный подход к бенчмаркингу

Если нужны надежные результаты:

function benchmark(fn, iterations = 1000) {
  const results = []
  
  // Прогреть код (JIT компиляция)
  for (let i = 0; i < 10; i++) {
    fn()
  }
  
  // Измерить
  for (let i = 0; i < iterations; i++) {
    const start = performance.now()
    fn()
    const end = performance.now()
    results.push(end - start)
  }
  
  // Вычислить статистику
  const avg = results.reduce((a, b) => a + b) / results.length
  const min = Math.min(...results)
  const max = Math.max(...results)
  
  return {
    average: avg.toFixed(3),
    min: min.toFixed(3),
    max: max.toFixed(3),
    iterations
  }
}

// Использование
const result = benchmark(() => {
  const arr = Array.from({ length: 100 }, (_, i) => i)
  arr.find(x => x === 50)
}, 1000)

console.log(result)
// {
//   average: "0.051ms",
//   min: "0.012ms",
//   max: "0.234ms",
//   iterations: 1000
// }

Вывод

Date.now() валидно, но не оптимально:

  • Для быстрого профилирования в разработке: console.time()
  • Для точного измерения в браузере: performance.now()
  • Для сложного анализа: performance.mark() и performance.measure()
  • Для бенчмарков: специализированные библиотеки типа Benchmark.js

Используй Date.now() только для грубых оценок интервалов (секунды и выше). Для микро-оптимизаций и точного профилирования используй Performance API.