🚀 Oferta especial: 60% OFF no CrazyStack - Últimas vagas!Garantir vaga →
MÓDULO 2 - AULA 6

Performance e Benchmarks

Medindo performance real. Comparações científicas e otimizações que fazem diferença no mundo real

🎯 Performance importa

Teoria é boa, mas números não mentem. Vamos medir cientificamente a diferença entre generators e arrays tradicionais, descobrir gargalos e otimizar para performance máxima.

📊 Benchmark Científico: Números reais

✅ Metodologia correta

Benchmarks ruins geram conclusões erradas. Vamos usar metodologia científica: múltiplas execuções, warm-up, isolamento de variáveis e medições precisas.

performance-benchmark.js
// 📊 BENCHMARK SUITE: Medições científicas
class PerformanceBenchmark {
  constructor() {
    this.results = [];
  }

  // ⏱️ TIMER PRECISO: Usa performance.now() para alta precisão
  async measureTime(fn, iterations = 1) {
    // 🔥 WARM-UP: Executa algumas vezes para JIT compiler
    for (let i = 0; i < 3; i++) {
      await fn();
    }
    
    const times = [];
    
    // 📊 MÚLTIPLAS EXECUÇÕES para estatística confiável
    for (let i = 0; i < iterations; i++) {
      const start = performance.now();
      await fn();
      const end = performance.now();
      times.push(end - start);
    }
    
    // 📊 ESTATÍSTICAS
    times.sort((a, b) => a - b);
    const min = times[0];
    const max = times[times.length - 1];
    const median = times[Math.floor(times.length / 2)];
    const avg = times.reduce((a, b) => a + b) / times.length;
    const stdDev = Math.sqrt(
      times.reduce((sum, time) => sum + Math.pow(time - avg, 2), 0) / times.length
    );
    
    return { min, max, median, avg, stdDev, iterations: times.length };
  }

  // 🧠 MEMORY USAGE: Mede uso de memória
  async measureMemory(fn) {
    // Force garbage collection se disponível (Node.js com --expose-gc)
    if (global.gc) global.gc();
    
    const before = process.memoryUsage();
    await fn();
    const after = process.memoryUsage();
    
    return {
      heapUsed: after.heapUsed - before.heapUsed,
      heapTotal: after.heapTotal - before.heapTotal,
      rss: after.rss - before.rss,
      external: after.external - before.external
    };
  }

  // 📊 BENCHMARK COMPARATIVO
  async compare(tests, iterations = 10) {
    console.log(`🧪 Executando ${tests.length} testes com ${iterations} iterações cada`);
    console.log('=' .repeat(60));
    
    const results = [];
    
    for (const [name, testFn] of tests) {
      console.log(`\n🔄 Executando: ${name}`);
      
      // ⏱️ TEMPO
      const timeStats = await this.measureTime(testFn, iterations);
      
      // 🧠 MEMÓRIA
      const memoryStats = await this.measureMemory(testFn);
      
      const result = {
        name,
        time: timeStats,
        memory: memoryStats
      };
      
      results.push(result);
      
      console.log(`  ⏱️ Tempo médio: ${timeStats.avg.toFixed(2)}ms (±${timeStats.stdDev.toFixed(2)})`);
      console.log(`  🧠 Heap usado: ${(memoryStats.heapUsed / 1024 / 1024).toFixed(2)}MB`);
    }
    
    // 📊 RELATÓRIO COMPARATIVO
    this.generateReport(results);
    return results;
  }

  generateReport(results) {
    console.log('\n📊 RELATÓRIO COMPARATIVO');
    console.log('=' .repeat(60));
    
    // 🏆 RANKING POR TEMPO
    const sortedByTime = [...results].sort((a, b) => a.time.avg - b.time.avg);
    console.log('\n🏃 RANKING POR VELOCIDADE:');
    sortedByTime.forEach((result, index) => {
      const speedup = index === 0 ? 1 : result.time.avg / sortedByTime[0].time.avg;
      console.log(`  ${index + 1}. ${result.name}: ${result.time.avg.toFixed(2)}ms (x${speedup.toFixed(2)})`);
    });
    
    // 🧠 RANKING POR MEMÓRIA
    const sortedByMemory = [...results].sort((a, b) => a.memory.heapUsed - b.memory.heapUsed);
    console.log('\n🧠 RANKING POR EFICIÊNCIA DE MEMÓRIA:');
    sortedByMemory.forEach((result, index) => {
      const efficiency = index === 0 ? 1 : result.memory.heapUsed / sortedByMemory[0].memory.heapUsed;
      const mb = (result.memory.heapUsed / 1024 / 1024).toFixed(2);
      console.log(`  ${index + 1}. ${result.name}: ${mb}MB (x${efficiency.toFixed(2)})`);
    });
  }
}

// 🧪 TESTES DE PERFORMANCE
async function runBenchmarks() {
  const benchmark = new PerformanceBenchmark();
  
  // 📊 DATASET para testes
  const DATASET_SIZE = 100000;
  
  const tests = [
    // ❌ TESTE 1: Array tradicional (carrega tudo)
    ['Array Tradicional', async () => {
      const data = [];
      for (let i = 0; i < DATASET_SIZE; i++) {
        data.push({
          id: i,
          value: `item-${i}`,
          processed: false
        });
      }
      
      // Processa todos
      const processed = data
        .map(item => ({ ...item, processed: true }))
        .filter(item => item.id % 2 === 0)
        .slice(0, 1000);
      
      return processed.length;
    }],
    
    // ✅ TESTE 2: Generator com early break
    ['Generator com Break', async () => {
      function* generateData() {
        for (let i = 0; i < DATASET_SIZE; i++) {
          yield {
            id: i,
            value: `item-${i}`,
            processed: false
          };
        }
      }
      
      const results = [];
      for (const item of generateData()) {
        const processed = { ...item, processed: true };
        if (processed.id % 2 === 0) {
          results.push(processed);
          if (results.length >= 1000) break; // 🚀 Para quando tem o suficiente!
        }
      }
      
      return results.length;
    }],
    
    // 🔧 TESTE 3: Generator com helpers
    ['Generator com Helpers', async () => {
      function* generateData() {
        for (let i = 0; i < DATASET_SIZE; i++) {
          yield {
            id: i,
            value: `item-${i}`,
            processed: false
          };
        }
      }
      
      // Pipeline helpers
      function* map(iterable, fn) {
        for (const item of iterable) {
          yield fn(item);
        }
      }
      
      function* filter(iterable, predicate) {
        for (const item of iterable) {
          if (predicate(item)) yield item;
        }
      }
      
      function* take(iterable, count) {
        let taken = 0;
        for (const item of iterable) {
          if (taken >= count) break;
          yield item;
          taken++;
        }
      }
      
      const pipeline = take(
        filter(
          map(generateData(), item => ({ ...item, processed: true })),
          item => item.id % 2 === 0
        ),
        1000
      );
      
      return [...pipeline].length;
    }]
  ];
  
  await benchmark.compare(tests, 5);
}

// 🚀 EXECUTAR BENCHMARKS
console.log('🚀 INICIANDO BENCHMARKS DE PERFORMANCE');
runBenchmarks();

🧠 Memory Profiling: Caçando vazamentos

⚠️ Memory leaks matam aplicações

Em produção, memory leaks são fatais. Aplicações ficam lentas, consomem RAM infinitamente e crasham. Vamos aprender a detectar e prevenir vazamentos.

memory-profiling.js
// 🕵️ MEMORY PROFILER: Detecta vazamentos e padrões
class MemoryProfiler {
  constructor() {
    this.snapshots = [];
    this.leakDetected = false;
  }

  // 📸 SNAPSHOT: Captura estado da memória
  takeSnapshot(label = 'snapshot') {
    const usage = process.memoryUsage();
    const snapshot = {
      label,
      timestamp: Date.now(),
      heapUsed: usage.heapUsed,
      heapTotal: usage.heapTotal,
      external: usage.external,
      rss: usage.rss
    };
    
    this.snapshots.push(snapshot);
    console.log(`📸 ${label}: ${(usage.heapUsed / 1024 / 1024).toFixed(2)}MB heap`);
    return snapshot;
  }

  // 📊 ANALISA CRESCIMENTO de memória
  analyzeGrowth() {
    if (this.snapshots.length < 2) return null;
    
    const first = this.snapshots[0];
    const last = this.snapshots[this.snapshots.length - 1];
    
    const growth = {
      heapGrowth: last.heapUsed - first.heapUsed,
      timeElapsed: last.timestamp - first.timestamp,
      avgGrowthRate: (last.heapUsed - first.heapUsed) / (last.timestamp - first.timestamp) * 1000 // bytes/sec
    };
    
    // 🚨 LEAK DETECTION: Crescimento > 10MB/min é suspeito
    if (growth.avgGrowthRate > (10 * 1024 * 1024 / 60)) {
      this.leakDetected = true;
      console.log('🚨 POSSÍVEL MEMORY LEAK DETECTADO!');
    }
    
    return growth;
  }

  // 📋 RELATÓRIO de memória
  generateReport() {
    console.log('\n🧠 RELATÓRIO DE MEMÓRIA');
    console.log('=' .repeat(40));
    
    this.snapshots.forEach((snapshot, index) => {
      const mb = (snapshot.heapUsed / 1024 / 1024).toFixed(2);
      console.log(`${index + 1}. ${snapshot.label}: ${mb}MB`);
    });
    
    const growth = this.analyzeGrowth();
    if (growth) {
      const growthMB = (growth.heapGrowth / 1024 / 1024).toFixed(2);
      const rateMB = (growth.avgGrowthRate / 1024 / 1024 * 60).toFixed(2);
      console.log(`\n📈 Crescimento total: ${growthMB}MB`);
      console.log(`⚡ Taxa de crescimento: ${rateMB}MB/min`);
      
      if (this.leakDetected) {
        console.log('🚨 STATUS: MEMORY LEAK DETECTADO');
      } else {
        console.log('✅ STATUS: Uso de memória normal');
      }
    }
  }
}

// 🧪 TESTE: Comparando uso de memória
async function memoryComparisonTest() {
  const profiler = new MemoryProfiler();
  
  console.log('🧪 TESTE DE USO DE MEMÓRIA: Arrays vs Generators');
  console.log('='.repeat(50));
  
  // 📸 Snapshot inicial
  profiler.takeSnapshot('Inicial');
  
  // ❌ TESTE 1: Array que vaza memória
  console.log('\n❌ Testando Array (potencial vazamento)...');
  const arrayData = [];
  
  for (let i = 0; i < 500000; i++) {
    arrayData.push({
      id: i,
      data: 'x'.repeat(100), // 100 bytes por item
      references: Array(10).fill('ref'), // Mais referências
      created: new Date()
    });
    
    // Snapshot a cada 100k itens
    if (i % 100000 === 0) {
      profiler.takeSnapshot(`Array - ${i} itens`);
    }
  }
  
  const processedArray = arrayData
    .filter(item => item.id % 2 === 0)
    .slice(0, 1000);
  
  profiler.takeSnapshot('Array - Processado');
  
  // 🧹 FORÇA limpeza (mas array ainda está na memória)
  if (global.gc) global.gc();
  profiler.takeSnapshot('Array - Após GC');
  
  console.log(`✅ Array processou ${processedArray.length} itens`);
  
  // ✅ TESTE 2: Generator eficiente
  console.log('\n✅ Testando Generator (memória controlada)...');
  
  function* generateData() {
    for (let i = 0; i < 500000; i++) {
      yield {
        id: i,
        data: 'x'.repeat(100),
        references: Array(10).fill('ref'),
        created: new Date()
      };
    }
  }
  
  let processedCount = 0;
  let iterationCount = 0;
  
  for (const item of generateData()) {
    if (item.id % 2 === 0) {
      processedCount++;
      if (processedCount >= 1000) break; // Para quando tem o suficiente
    }
    
    iterationCount++;
    
    // Snapshot a cada 100k iterações
    if (iterationCount % 100000 === 0) {
      profiler.takeSnapshot(`Generator - ${iterationCount} iterações`);
    }
  }
  
  profiler.takeSnapshot('Generator - Finalizado');
  
  // 🧹 Limpeza
  if (global.gc) global.gc();
  profiler.takeSnapshot('Generator - Após GC');
  
  console.log(`✅ Generator processou ${processedCount} itens úteis`);
  console.log(`📊 Total de iterações: ${iterationCount}`);
  
  // 📊 Relatório final
  profiler.generateReport();
}

// 🚀 EXECUTAR TESTE
memoryComparisonTest();

// 📊 RESULTADO ESPERADO:
// Array: Crescimento linear ~50MB para 500k itens
// Generator: Uso constante ~1-2MB independente do tamanho
// 
// 🏆 VANTAGEM GENERATOR:
// - 25x menos memória
// - Sem vazamentos
// - Performance linear O(n)
// - Early termination funciona

⚡ Otimizações Avançadas: Squeezing performance

🚀 Otimizações que importam

Detalhes fazem diferença. Vamos ver técnicas avançadas que podem dar 2x-5x mais performance: memoização, object pooling, typed arrays e JIT optimizations.

advanced-optimizations.js
// ⚡ OTIMIZAÇÕES AVANÇADAS para máxima performance
class OptimizedGenerator {
  constructor() {
    // 🏊 OBJECT POOL: Reutiliza objetos para evitar GC pressure
    this.objectPool = [];
    this.poolSize = 1000;
    this.initializePool();
    
    // 🧠 MEMOIZAÇÃO: Cache para cálculos caros
    this.memoCache = new Map();
    this.maxCacheSize = 10000;
  }

  // 🏊 INICIALIZA object pool
  initializePool() {
    for (let i = 0; i < this.poolSize; i++) {
      this.objectPool.push(this.createEmptyObject());
    }
  }

  // 🏗️ FACTORY: Cria objeto otimizado
  createEmptyObject() {
    return {
      id: 0,
      value: '',
      computed: 0,
      metadata: null,
      processed: false
    };
  }

  // 🔄 REUSA objeto do pool
  getObjectFromPool() {
    return this.objectPool.pop() || this.createEmptyObject();
  }

  // 🔙 RETORNA objeto para pool
  returnObjectToPool(obj) {
    if (this.objectPool.length < this.poolSize) {
      // Reset object state
      obj.id = 0;
      obj.value = '';
      obj.computed = 0;
      obj.metadata = null;
      obj.processed = false;
      
      this.objectPool.push(obj);
    }
  }

  // 🧠 MEMOIZED COMPUTATION: Cache cálculos caros
  memoizedCompute(input) {
    if (this.memoCache.has(input)) {
      return this.memoCache.get(input);
    }
    
    // Simula cálculo caro (fibonacci, hash, etc.)
    let result = 0;
    for (let i = 0; i < 1000; i++) {
      result += Math.sin(input + i) * Math.cos(input - i);
    }
    
    // Mantém cache limitado para evitar memory leak
    if (this.memoCache.size >= this.maxCacheSize) {
      const firstKey = this.memoCache.keys().next().value;
      this.memoCache.delete(firstKey);
    }
    
    this.memoCache.set(input, result);
    return result;
  }

  // 🚀 GENERATOR OTIMIZADO
  * generateOptimizedData(count = 100000) {
    // 📊 TYPED ARRAY para dados numéricos (mais eficiente)
    const numericData = new Float32Array(1000);
    let batchIndex = 0;
    
    for (let i = 0; i < count; i++) {
      // 🏊 REUSA objeto do pool
      const obj = this.getObjectFromPool();
      
      // 🔧 POPULANDO objeto
      obj.id = i;
      obj.value = `item-${i}`;
      obj.processed = true;
      
      // 🧠 CÁLCULO MEMOIZADO
      obj.computed = this.memoizedCompute(i % 100); // Limita entradas para melhor cache hit
      
      // 📊 TYPED ARRAY para dados numéricos
      const arrayIndex = i % 1000;
      numericData[arrayIndex] = obj.computed;
      
      // 🎯 METADATA só quando necessário (lazy)
      if (i % 1000 === 0) {
        obj.metadata = {
          batchIndex: Math.floor(i / 1000),
          avgComputed: numericData.reduce((a, b) => a + b) / 1000,
          timestamp: Date.now()
        };
        batchIndex++;
      }
      
      yield obj;
      
      // 🔙 RETORNA para pool após uso
      this.returnObjectToPool(obj);
    }
  }

  // 📊 STATS do cache
  getCacheStats() {
    return {
      size: this.memoCache.size,
      maxSize: this.maxCacheSize,
      hitRate: this.cacheHits / (this.cacheHits + this.cacheMisses) || 0,
      poolSize: this.objectPool.length
    };
  }
}

// 🧪 BENCHMARK: Comparando otimizações
async function optimizationBenchmark() {
  console.log('⚡ BENCHMARK: Otimizações Avançadas');
  console.log('=' .repeat(40));
  
  const ITEMS = 50000;
  
  // ❌ TESTE 1: Generator básico (não otimizado)
  console.time('Generator Básico');
  function* basicGenerator() {
    for (let i = 0; i < ITEMS; i++) {
      // ❌ Cria novo objeto a cada iteração (GC pressure)
      const obj = {
        id: i,
        value: `item-${i}`,
        processed: true,
        // ❌ Cálculo caro repetido
        computed: (() => {
          let result = 0;
          for (let j = 0; j < 1000; j++) {
            result += Math.sin(i + j) * Math.cos(i - j);
          }
          return result;
        })(),
        metadata: {
          timestamp: Date.now(),
          batch: Math.floor(i / 1000)
        }
      };
      yield obj;
    }
  }
  
  let basicCount = 0;
  for (const item of basicGenerator()) {
    basicCount++;
    if (basicCount >= 10000) break;
  }
  console.timeEnd('Generator Básico');
  console.log(`✅ Processados: ${basicCount} itens`);
  
  // ✅ TESTE 2: Generator otimizado
  console.time('Generator Otimizado');
  const optimized = new OptimizedGenerator();
  
  let optimizedCount = 0;
  for (const item of optimized.generateOptimizedData(ITEMS)) {
    optimizedCount++;
    if (optimizedCount >= 10000) break;
  }
  console.timeEnd('Generator Otimizado');
  console.log(`✅ Processados: ${optimizedCount} itens`);
  
  // 📊 ESTATÍSTICAS
  const stats = optimized.getCacheStats();
  console.log('\n📊 ESTATÍSTICAS DE OTIMIZAÇÃO:');
  console.log(`🧠 Cache size: ${stats.size}/${stats.maxSize}`);
  console.log(`🏊 Pool size: ${stats.poolSize}`);
  
  // 🧠 Memory usage após teste
  const memUsage = process.memoryUsage();
  console.log(`💾 Heap usado: ${(memUsage.heapUsed / 1024 / 1024).toFixed(2)}MB`);
}

// 🚀 EXECUTAR BENCHMARK
optimizationBenchmark();

// 📊 TÉCNICAS DE OTIMIZAÇÃO USADAS:
// 
// 1. 🏊 OBJECT POOLING
//    - Reutiliza objetos ao invés de criar novos
//    - Reduz pressure no garbage collector
//    - 30-50% menos tempo em GC
//
// 2. 🧠 MEMOIZAÇÃO
//    - Cache de cálculos caros
//    - Hit rate > 90% em padrões repetitivos  
//    - 10x mais rápido para cálculos complexos
//
// 3. 📊 TYPED ARRAYS
//    - Float32Array para dados numéricos
//    - 50% menos memória que arrays normais
//    - Acesso mais rápido
//
// 4. 🎯 LAZY EVALUATION
//    - Metadata só quando necessário
//    - Evita computação desnecessária
//    - Reduz CPU usage em 20-40%

// 🏆 RESULTADO ESPERADO:
// Generator Otimizado: 2-5x mais rápido que básico
// Menos GC pauses, menor uso de memória

📈 Métricas em Produção: Monitoramento real

Métricas de Performance

Throughput: Items/segundo processados

Latência: Tempo por operação

CPU Usage: % de uso do processador

Memory: Heap size e growth rate

Alertas Críticos

Memory Leak: Crescimento > 10MB/min

Performance: Latência > 100ms

Throughput: Queda > 50%

CPU: Uso sustentado > 80%

production-metrics.js
// 📊 PRODUCTION METRICS: Monitoramento em tempo real
class ProductionMetrics {
  constructor() {
    this.metrics = {
      throughput: [],
      latency: [],
      memoryUsage: [],
      cpuUsage: [],
      errors: 0,
      totalProcessed: 0
    };
    
    this.alerts = [];
    this.startTime = Date.now();
  }

  // 📊 COLETA métricas durante processamento
  recordMetric(type, value) {
    const timestamp = Date.now();
    this.metrics[type].push({ value, timestamp });
    
    // Mantém apenas últimos 1000 pontos para evitar memory leak
    if (this.metrics[type].length > 1000) {
      this.metrics[type].shift();
    }
    
    // 🚨 VERIFICA alertas
    this.checkAlerts(type, value);
  }

  // 🚨 SISTEMA de alertas
  checkAlerts(type, value) {
    const alerts = {
      latency: { threshold: 100, message: 'Alta latência detectada' },
      memoryGrowth: { threshold: 10485760, message: 'Possível memory leak' }, // 10MB
      cpuUsage: { threshold: 80, message: 'Alto uso de CPU' },
      errorRate: { threshold: 0.05, message: 'Taxa de erro elevada' }
    };
    
    if (alerts[type] && value > alerts[type].threshold) {
      this.alerts.push({
        type,
        value,
        threshold: alerts[type].threshold,
        message: alerts[type].message,
        timestamp: Date.now()
      });
      
      console.log(`🚨 ALERTA: ${alerts[type].message} (${value})`);
    }
  }

  // 📊 DASHBOARD em tempo real
  displayDashboard() {
    const uptime = Date.now() - this.startTime;
    const uptimeMin = Math.floor(uptime / 60000);
    
    console.clear();
    console.log('📊 PRODUCTION DASHBOARD');
    console.log('=' .repeat(50));
    console.log(`⏱️ Uptime: ${uptimeMin} minutos`);
    console.log(`📦 Total processado: ${this.metrics.totalProcessed}`);
    console.log(`❌ Erros: ${this.metrics.errors}`);
    
    // 📊 Últimas métricas
    const lastLatency = this.getLastMetric('latency');
    const lastMemory = this.getLastMetric('memoryUsage');
    const lastThroughput = this.getThroughput();
    
    console.log('\n📈 MÉTRICAS ATUAIS:');
    console.log(`⚡ Throughput: ${lastThroughput.toFixed(1)} items/sec`);
    console.log(`⏱️ Latência: ${lastLatency?.toFixed(2) || 'N/A'}ms`);
    console.log(`🧠 Memória: ${(lastMemory / 1024 / 1024).toFixed(2)}MB`);
    
    // 🚨 Alertas ativos
    const recentAlerts = this.alerts.filter(a => Date.now() - a.timestamp < 300000); // 5 min
    if (recentAlerts.length > 0) {
      console.log('\n🚨 ALERTAS ATIVOS:');
      recentAlerts.forEach(alert => {
        console.log(`  • ${alert.message} (${alert.value})`);
      });
    }
  }

  getLastMetric(type) {
    const metrics = this.metrics[type];
    return metrics.length > 0 ? metrics[metrics.length - 1].value : null;
  }

  getThroughput() {
    const throughputMetrics = this.metrics.throughput;
    if (throughputMetrics.length < 2) return 0;
    
    const recent = throughputMetrics.slice(-10); // Últimos 10 pontos
    const timeSpan = recent[recent.length - 1].timestamp - recent[0].timestamp;
    const itemsProcessed = recent.reduce((sum, m) => sum + m.value, 0);
    
    return (itemsProcessed / timeSpan) * 1000; // items/sec
  }

  // 📊 RELATÓRIO FINAL
  generateReport() {
    console.log('\n📊 RELATÓRIO FINAL DE PERFORMANCE');
    console.log('=' .repeat(40));
    
    const totalTime = Date.now() - this.startTime;
    const avgThroughput = this.metrics.totalProcessed / (totalTime / 1000);
    
    console.log(`⏱️ Tempo total: ${(totalTime / 1000).toFixed(2)}s`);
    console.log(`📦 Total processado: ${this.metrics.totalProcessed}`);
    console.log(`⚡ Throughput médio: ${avgThroughput.toFixed(2)} items/sec`);
    console.log(`❌ Total de erros: ${this.metrics.errors}`);
    console.log(`🚨 Total de alertas: ${this.alerts.length}`);
    
    // 📊 Estatísticas por métrica
    ['latency', 'memoryUsage'].forEach(type => {
      const metrics = this.metrics[type];
      if (metrics.length > 0) {
        const values = metrics.map(m => m.value);
        const avg = values.reduce((a, b) => a + b) / values.length;
        const max = Math.max(...values);
        const min = Math.min(...values);
        
        console.log(`\n📊 ${type.toUpperCase()}:`);
        console.log(`  Média: ${avg.toFixed(2)}`);
        console.log(`  Máximo: ${max.toFixed(2)}`);
        console.log(`  Mínimo: ${min.toFixed(2)}`);
      }
    });
  }
}

// 🚀 EXEMPLO DE USO em produção
async function productionSimulation() {
  const metrics = new ProductionMetrics();
  
  // 📊 DASHBOARD timer
  const dashboardInterval = setInterval(() => {
    metrics.displayDashboard();
  }, 2000);
  
  try {
    // 🏭 SIMULA processamento em produção
    function* productionDataStream() {
      for (let i = 0; i < 100000; i++) {
        yield {
          id: i,
          data: `production-item-${i}`,
          timestamp: Date.now()
        };
      }
    }
    
    let processed = 0;
    
    for (const item of productionDataStream()) {
      const start = performance.now();
      
      // 🔧 SIMULA processamento
      await new Promise(resolve => setTimeout(resolve, Math.random() * 10));
      
      const end = performance.now();
      const latency = end - start;
      
      // 📊 COLETA métricas
      metrics.recordMetric('latency', latency);
      metrics.recordMetric('throughput', 1);
      metrics.recordMetric('memoryUsage', process.memoryUsage().heapUsed);
      
      metrics.metrics.totalProcessed++;
      processed++;
      
      // 🛑 DEMO: Para após 1000 itens
      if (processed >= 1000) break;
    }
    
  } finally {
    clearInterval(dashboardInterval);
    metrics.generateReport();
  }
}

// 🚀 INICIAR simulação
// productionSimulation();

🚀 Checkpoint: Performance Expert

Benchmarks CientíficosMemory ProfilingOtimizações AvançadasMétricas Produção

Agora você sabe medir, otimizar e monitorar performance em aplicações reais!