perf_hooks moduli


ULASHISH

Ishlash hook’lari nima?

perf_hooks moduli W3C Performance Timeline spetsifikatsiyasi asosida unumdorlikni o‘lchash uchun API to‘plamini taqdim etadi.

Ushbu vositalar quyidagilar uchun zarurdir:

  • Muayyan operatsiyalar uchun vaqtni o‘lchash
  • Ishlashdagi qiyinchiliklarni topish
  • Turli xil ilovalarning samaradorligini taqqoslash
  • Vaqt o‘tishi bilan dastur ishlashini kuzatish

Modul yuqori aniqlikdagi taymerlar, ishlash belgilari, o‘lchovlar, kuzatuvchilar va gistogrammalar kabi bir nechta foydali xususiyatlarni o‘z ichiga oladi.


Performance Hooks modulidan foydalanish

Performance Hooks modulidan foydalanish uchun uni kodingizda talab qilishingiz kerak:

// Import the entire module
const { performance, PerformanceObserver } = require('perf_hooks');

// Or using destructuring for specific parts
const { performance } = require('perf_hooks');
Misolni ishga tushirish »

Asosiy vaqtni o‘lchash

Performans API-dan eng asosiy foydalanish o‘tgan vaqtni yuqori aniqlik bilan o‘lchashdir:

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

// Get the current high-resolution time
const startTime = performance.now();

// Perform some operation
let sum = 0;
for (let i = 0; i < 1000000; i++) {
  sum += i;
}

// Get the end time
const endTime = performance.now();

// Calculate and display the elapsed time in milliseconds
console.log(`Operation took ${(endTime - startTime).toFixed(2)} milliseconds`);
Misolni ishga tushirish »

performance.now() usuli joriy Node.js jarayoni boshlangan paytdan boshlab o‘lchangan millisekundlarda yuqori aniqlikdagi vaqt tamg‘asini qaytaradi.



Ishlash belgilari va o‘lchovlari

Belgilar

Ishlash belgilari - bu siz kuzatmoqchi bo‘lgan muayyan vaqt nuqtalari:

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

// Create marks at specific points in your code
performance.mark('startProcess');

// Simulate some work
let result = 0;
for (let i = 0; i < 1000000; i++) {
  result += Math.sqrt(i);
}

// Create another mark
performance.mark('endProcess');

// Get all the marks
console.log(performance.getEntriesByType('mark'));
Misolni ishga tushirish »

Chora-tadbirlar

Ishlash ko‘rsatkichlari ikki belgi orasidagi vaqtni hisoblab chiqadi:

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

// Create a start mark
performance.mark('start');

// Simulate some work
let result = 0;
for (let i = 0; i < 1000000; i++) {
  result += Math.sqrt(i);
}

// Create an end mark
performance.mark('end');

// Create a measure between the two marks
performance.measure('processTime', 'start', 'end');

// Get the measure
const measure = performance.getEntriesByName('processTime')[0];
console.log(`Process took ${measure.duration.toFixed(2)} milliseconds`);

// Clear marks and measures
performance.clearMarks();
performance.clearMeasures();
Misolni ishga tushirish »

Ishlash kuzatuvchisi

PerformanceObserver ishlash hodisalarini asinxron kuzatish imkonini beradi:

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

// Create a performance observer
const obs = new PerformanceObserver((items) => {
  // Process all entries
  const entries = items.getEntries();
  entries.forEach((entry) => {
    console.log(`Name: ${entry.name}, Type: ${entry.entryType}, Duration: ${entry.duration.toFixed(2)}ms`);
  });
});

// Subscribe to specific entry types
obs.observe({ entryTypes: ['measure'] });

// First task
performance.mark('task1Start');
// Simulate work
setTimeout(() => {
  performance.mark('task1End');
  performance.measure('Task 1', 'task1Start', 'task1End');
  
  // Second task
  performance.mark('task2Start');
  setTimeout(() => {
    performance.mark('task2End');
    performance.measure('Task 2', 'task2Start', 'task2End');
    
    // Clean up
    performance.clearMarks();
    performance.clearMeasures();
    obs.disconnect();
  }, 1000);
}, 1000);
Misolni ishga tushirish »

Performance Timeline API

Performance Timeline API unumdorlik yozuvlarini olish usullarini taqdim etadi:

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

// Create some performance entries
performance.mark('mark1');
performance.mark('mark2');

let sum = 0;
for (let i = 0; i < 100000; i++) {
  sum += i;
}

performance.mark('mark3');
performance.measure('measure1', 'mark1', 'mark2');
performance.measure('measure2', 'mark2', 'mark3');

// Get all performance entries
console.log('All entries:');
console.log(performance.getEntries());

// Get entries by type
console.log('\nMarks:');
console.log(performance.getEntriesByType('mark'));

// Get entries by name
console.log('\nMeasure 1:');
console.log(performance.getEntriesByName('measure1'));
Misolni ishga tushirish »

Ishlash vaqtini belgilash darajalari

Node.js turli darajadagi aniqlik bilan ishlash vaqtining turli API-larini taqdim etadi:

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

// 1. Date.now() - millisecond precision
const dateStart = Date.now();
const dateEnd = Date.now();
console.log(`Date.now() difference: ${dateEnd - dateStart}ms`);

// 2. process.hrtime() - nanosecond precision
const hrStart = process.hrtime();
const hrEnd = process.hrtime(hrStart);
console.log(`process.hrtime() difference: ${hrEnd[0]}s ${hrEnd[1]}ns`);

// 3. performance.now() - microsecond precision
const perfStart = performance.now();
const perfEnd = performance.now();
console.log(`performance.now() difference: ${(perfEnd - perfStart).toFixed(6)}ms`);

// 4. Event loop delay monitoring (available in Node.js 12.0.0+)
const histogram = monitorEventLoopDelay({ resolution: 20 });
histogram.enable();

setTimeout(() => {
  histogram.disable();
  console.log('Event loop delay metrics:');
  console.log(`  Min: ${histogram.min}ns`);
  console.log(`  Max: ${histogram.max}ns`);
  console.log(`  Mean: ${histogram.mean.toFixed(2)}ns`);
  console.log(`  Stddev: ${histogram.stddev.toFixed(2)}ns`);
  console.log(`  Percentiles: 50=${histogram.percentile(50).toFixed(2)}ns, 99=${histogram.percentile(99).toFixed(2)}ns`);
}, 1000);
Misolni ishga tushirish »

Hodisa sikli monitoringi

monitorEventLoopDelay funksiyasi hodisa siklidagi kechikishni kuzatish usulini taqdim etadi:

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

// Create a histogram
const histogram = monitorEventLoopDelay({ resolution: 10 });

// Enable monitoring
histogram.enable();

// Simulate load on the event loop
const operations = [];
for (let i = 0; i < 10; i++) {
  operations.push(new Promise((resolve) => {
    setTimeout(() => {
      // Simulate CPU-intensive work
      let sum = 0;
      for (let j = 0; j < 10000000; j++) {
        sum += j;
      }
      resolve(sum);
    }, 100);
  }));
}

// After all operations complete
Promise.all(operations).then(() => {
  // Disable monitoring
  histogram.disable();
  
  // Print statistics
  console.log('Event Loop Delay Statistics:');
  console.log(`  Min: ${histogram.min}ns`);
  console.log(`  Max: ${histogram.max}ns`);
  console.log(`  Mean: ${histogram.mean.toFixed(2)}ns`);
  console.log(`  Stddev: ${histogram.stddev.toFixed(2)}ns`);
  
  // Percentiles
  console.log('\nPercentiles:');
  [1, 10, 50, 90, 99, 99.9].forEach((p) => {
    console.log(`  p${p}: ${histogram.percentile(p).toFixed(2)}ns`);
  });
});
Misolni ishga tushirish »

Voqealar siklini monitoring qilish, ayniqsa, uzoq vaqt davomida bajariladigan vazifalar tufayli, voqea siklini blokirovka qilgan holda, ilovangiz javob berishda muammolarga duch kelishi mumkinligini aniqlash uchun ayniqsa foydalidir.


Asenkron operatsiyalarda ishlashni kuzatish

Asinxron operatsiyalarda ishlashni kuzatish diqqat bilan belgi qo‘yishni talab qiladi:

const { performance, PerformanceObserver } = require('perf_hooks');
const fs = require('fs');

// Create observer for the measures
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration.toFixed(2)}ms`);
  });
});
obs.observe({ entryTypes: ['measure'] });

// Measure async file read operation
performance.mark('readStart');

fs.readFile(__filename, (err, data) => {
  if (err) throw err;
  
  performance.mark('readEnd');
  performance.measure('File Read', 'readStart', 'readEnd');
  
  // Measure async processing time
  performance.mark('processStart');
  
  // Simulate processing the file data
  setTimeout(() => {
    const lines = data.toString().split('\n').length;
    
    performance.mark('processEnd');
    performance.measure('File Processing', 'processStart', 'processEnd');
    
    console.log(`File has ${lines} lines`);
    
    // Clean up
    performance.clearMarks();
    performance.clearMeasures();
  }, 100);
});
Misolni ishga tushirish »

Promiselarni kuzatish

Promiselarning bajarilishini o‘lchash shunga o‘xshash usullarni talab qiladi:

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

// Set up the observer
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration.toFixed(2)}ms`);
  });
});
obs.observe({ entryTypes: ['measure'] });

// Function that returns a promise
function fetchData(delay) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ data: 'Sample data' });
    }, delay);
  });
}

// Function to process data
function processData(data) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ processed: data.data.toUpperCase() });
    }, 200);
  });
}

// Measure Promise chain
async function run() {
  performance.mark('fetchStart');
  
  const data = await fetchData(300);
  
  performance.mark('fetchEnd');
  performance.mark('processStart');
  
  const processed = await processData(data);
  
  performance.mark('processEnd');
  
  // Create measures
  performance.measure('Fetch Data', 'fetchStart', 'fetchEnd');
  performance.measure('Process Data', 'processStart', 'processEnd');
  performance.measure('Total Operation', 'fetchStart', 'processEnd');
  
  console.log('Result:', processed);
}

run().finally(() => {
  // Clear after execution
  performance.clearMarks();
  performance.clearMeasures();
});
Misolni ishga tushirish »

Ishlash vaqti bo‘yicha ogohlantirishlar

Ishlash API-laridan foydalanganda ba’zi ogohlantirishlardan xabardor bo‘ling:

  • Vaqt o‘lchamlari platformalar orasida farq qiladi
  • Soatning siljishi uzoq davom etadigan jarayonlarda paydo bo‘lishi mumkin
  • Fondagi faoliyat vaqtni o‘lchashga ta’sir qilishi mumkin
  • JavaScript JIT kompilyatsiyasi birinchi ishga tushirish vaqtlarining mos kelmasligiga olib kelishi mumkin
const { performance } = require('perf_hooks');

// For accurate benchmarking, perform multiple runs
function benchmark(fn, iterations = 1000) {
  // Warm-up run (for JIT optimization)
  fn();
  
  const times = [];
  
  for (let i = 0; i < iterations; i++) {
    const start = performance.now();
    fn();
    const end = performance.now();
    times.push(end - start);
  }
  
  // Calculate statistics
  times.sort((a, b) => a - b);
  
  const sum = times.reduce((a, b) => a + b, 0);
  const avg = sum / times.length;
  const median = times[Math.floor(times.length / 2)];
  const min = times[0];
  const max = times[times.length - 1];
  
  return {
    average: avg,
    median: median,
    min: min,
    max: max,
    samples: times.length
  };
}

// Example usage
function testFunction() {
  // Function to benchmark
  let x = 0;
  for (let i = 0; i < 10000; i++) {
    x += i;
  }
  return x;
}

const results = benchmark(testFunction);
console.log('Benchmark Results:');
console.log(`  Samples: ${results.samples}`);
console.log(`  Average: ${results.average.toFixed(4)}ms`);
console.log(`  Median: ${results.median.toFixed(4)}ms`);
console.log(`  Min: ${results.min.toFixed(4)}ms`);
console.log(`  Max: ${results.max.toFixed(4)}ms`);
Misolni ishga tushirish »

NodeJS Performance Hooks va Brauzer Performance API

Node.js Performance Hooks API W3C Performance Timeline spetsifikatsiyasiga asoslangan, ammo brauzerning Performance API bilan solishtirganda ba’zi farqlar mavjud:

Xususiyat Browser Performance API Node.js ishlash hook’lari
Vaqtning kelib chiqishi Sahifani navigatsiya qilishni boshlash Jarayonni boshlash vaqti
Resurs vaqti Mavjud Qo‘llanilmaydigan, qo‘llab bo‘lmaydigan
Navigatsiya vaqti Mavjud Qo‘llanilmaydigan, qo‘llab bo‘lmaydigan
User Timing (mark/measure) Mavjud Mavjud
Yuqori aniqlik vaqti Mavjud Mavjud
Hodisa sikli monitoringi Cheklangan Mavjud

Amaliy misol: API ishlash monitoringi

API endpointlarini kuzatish uchun performance hooklaridan foydalanishning amaliy misoli:

const { performance, PerformanceObserver } = require('perf_hooks');
const express = require('express');
const app = express();
const port = 8080;

// Set up performance observer for logging
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`[${new Date().toISOString()}] ${entry.name}: ${entry.duration.toFixed(2)}ms`);
  });
});
obs.observe({ entryTypes: ['measure'] });

// Middleware to track request processing time
app.use((req, res, next) => {
  const start = performance.now();
  const requestId = `${req.method} ${req.url} ${Date.now()}`;
  
  // Mark the start of request processing
  performance.mark(`${requestId}-start`);
  
  // Override end method to capture when response is sent
  const originalEnd = res.end;
  res.end = function(...args) {
    performance.mark(`${requestId}-end`);
    performance.measure(
      `Request ${req.method} ${req.url}`,
      `${requestId}-start`,
      `${requestId}-end`
    );
    
    // Clean up marks
    performance.clearMarks(`${requestId}-start`);
    performance.clearMarks(`${requestId}-end`);
    
    return originalEnd.apply(this, args);
  };
  
  next();
});

// API routes
app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.get('/fast', (req, res) => {
  res.send('Fast response!');
});

app.get('/slow', (req, res) => {
  // Simulate a slow API endpoint
  setTimeout(() => {
    res.send('Slow response after delay');
  }, 500);
});

app.get('/process', (req, res) => {
  // Simulate CPU-intensive processing
  const requestId = `process-${Date.now()}`;
  performance.mark(`${requestId}-process-start`);
  
  let result = 0;
  for (let i = 0; i < 1000000; i++) {
    result += Math.sqrt(i);
  }
  
  performance.mark(`${requestId}-process-end`);
  performance.measure(
    'CPU Processing',
    `${requestId}-process-start`,
    `${requestId}-process-end`
  );
  
  res.send(`Processed result: ${result}`);
});

// Start server
app.listen(port, () => {
  console.log(`Performance monitoring example running at http://localhost:${port}`);
});
Misolni ishga tushirish »

Kengaytirilgan ishlash monitoringi

Ishlab chiqarish darajasidagi ilovalar uchun ushbu ilg‘or monitoring usullarini ko‘rib chiqing:

1. Xotira oqishini aniqlash

Ishlash hook’lari va Node.js xotira monitoringi yordamida xotira oqishini aniqlang va tahlil qiling:

const { performance, PerformanceObserver } = require('perf_hooks');
const { performance: perf } = require('process');

class MemoryMonitor {
  constructor() {
    this.leakThreshold = 10 * 1024 * 1024; // 10MB
    this.checkInterval = 10000; // 10 seconds
    this.interval = null;
    this.lastMemoryUsage = process.memoryUsage();
    this.leakDetected = false;
    
    // Set up performance observer for GC events
    const obs = new PerformanceObserver((items) => {
      items.getEntries().forEach((entry) => {
        if (entry.name === 'gc') {
          this.checkMemoryLeak();
        }
      });
    });
    obs.observe({ entryTypes: ['gc'] });
  }
  
  start() {
    console.log('Memory monitoring started');
    this.interval = setInterval(() => this.checkMemoryLeak(), this.checkInterval);
  }
  
  stop() {
    if (this.interval) {
      clearInterval(this.interval);
      console.log('Memory monitoring stopped');
    }
  }
  
  checkMemoryLeak() {
    const current = process.memoryUsage();
    const heapDiff = current.heapUsed - this.lastMemoryUsage.heapUsed;
    
    if (heapDiff > this.leakThreshold) {
      this.leakDetected = true;
      console.warn(`⚠️  Possible memory leak detected: Heap increased by ${(heapDiff / 1024 / 1024).toFixed(2)}MB`);
      console.log('Memory snapshot:', {
        rss: this.formatMemory(current.rss),
        heapTotal: this.formatMemory(current.heapTotal),
        heapUsed: this.formatMemory(current.heapUsed),
        external: this.formatMemory(current.external)
      });
      
      // Take a heap snapshot if needed
      if (process.env.NODE_ENV === 'development') {
        this.takeHeapSnapshot();
      }
    }
    
    this.lastMemoryUsage = current;
  }
  
  formatMemory(bytes) {
    return `${(bytes / 1024 / 1024).toFixed(2)}MB`;
  }
  
  takeHeapSnapshot() {
    const heapdump = require('heapdump');
    const filename = `heapdump-${Date.now()}.heapsnapshot`;
    heapdump.writeSnapshot(filename, (err, filename) => {
      if (err) {
        console.error('Failed to take heap snapshot:', err);
      } else {
        console.log(`Heap snapshot written to ${filename}`);
      }
    });
  }
}

// Usage example
const monitor = new MemoryMonitor();
monitor.start();

// Simulate a memory leak
const leaks = [];
setInterval(() => {
  for (let i = 0; i < 1000; i++) {
    leaks.push(new Array(1000).fill('*'.repeat(100)));
  }
}, 1000);

// Stop monitoring after 1 minute
setTimeout(() => {
  monitor.stop();
  console.log('Memory monitoring completed');
}, 60000);
Misolni ishga tushirish »

Eslatma: Xotira oqishini aniqlash misoli heapdump paketini talab qiladi. Uni npm install heapdump yordamida o‘rnating.

2. Maxsus ishlash ko‘rsatkichlari

Vaqt haqida batafsil ma’lumotga ega bo‘lgan maxsus ishlash ko‘rsatkichlarini yarating va kuzatib boring:

const { performance, PerformanceObserver, PerformanceEntry } = require('perf_hooks');

class PerformanceTracker {
  constructor() {
    this.metrics = new Map();
    this.observers = new Map();
    
    // Set up default observer for custom metrics
    this.setupDefaultObserver();
  }
  
  setupDefaultObserver() {
    const obs = new PerformanceObserver((items) => {
      items.getEntries().forEach((entry) => {
        if (!this.metrics.has(entry.name)) {
          this.metrics.set(entry.name, []);
        }
        this.metrics.get(entry.name).push(entry);
        
        // Log detailed metrics
        this.logMetric(entry);
      });
    });
    
    obs.observe({ entryTypes: ['measure'] });
    this.observers.set('default', obs);
  }
  
  startTimer(name) {
    performance.mark(`${name}-start`);
  }
  
  endTimer(name, attributes = {}) {
    performance.mark(`${name}-end`);
    performance.measure(name, {
      start: `${name}-start`,
      end: `${name}-end`,
      ...attributes
    });
    
    // Clean up marks
    performance.clearMarks(`${name}-start`);
    performance.clearMarks(`${name}-end`);
  }
  
  logMetric(entry) {
    const { name, duration, startTime, entryType, detail } = entry;
    console.log(`📊 [${new Date().toISOString()}] ${name}: ${duration.toFixed(2)}ms`);
    
    if (detail) {
      console.log('   Details:', JSON.stringify(detail, null, 2));
    }
  }
  
  getMetrics(name) {
    return this.metrics.get(name) || [];
  }
  
  getStats(name) {
    const metrics = this.getMetrics(name);
    if (metrics.length === 0) return null;
    
    const durations = metrics.map(m => m.duration);
    const sum = durations.reduce((a, b) => a + b, 0);
    const avg = sum / durations.length;
    
    return {
      count: durations.length,
      total: sum,
      average: avg,
      min: Math.min(...durations),
      max: Math.max(...durations),
      p90: this.percentile(durations, 90),
      p95: this.percentile(durations, 95),
      p99: this.percentile(durations, 99)
    };
  }
  
  percentile(arr, p) {
    if (!arr.length) return 0;
    const sorted = [...arr].sort((a, b) => a - b);
    const pos = (sorted.length - 1) * p / 100;
    const base = Math.floor(pos);
    const rest = pos - base;
    
    if (sorted[base + 1] !== undefined) {
      return sorted[base] + rest * (sorted[base + 1] - sorted[base]);
    } else {
      return sorted[base];
    }
  }
}

// Usage example
const tracker = new PerformanceTracker();

// Track a simple operation
tracker.startTimer('database-query');
setTimeout(() => {
  tracker.endTimer('database-query', {
    detail: {
      query: 'SELECT * FROM users',
      params: { limit: 100 },
      success: true
    }
  });
  
  // Get statistics
  console.log('Stats:', tracker.getStats('database-query'));
}, 200);
Misolni ishga tushirish »

Ishlash hook’lari bilan taqsimlangan kuzatuv

Ishlash hook’lari yordamida mikroservislar bo‘ylab taqsimlangan kuzatuvni amalga oshiring:

const { performance, PerformanceObserver } = require('perf_hooks');
const crypto = require('crypto');

class Tracer {
  constructor(serviceName) {
    this.serviceName = serviceName;
    this.spans = new Map();
    this.exportInterval = setInterval(() => this.exportSpans(), 10000);
  }
  
  startSpan(name, parentSpanId = null) {
    const spanId = crypto.randomBytes(8).toString('hex');
    const traceId = parentSpanId ? this.spans.get(parentSpanId)?.traceId : crypto.randomBytes(16).toString('hex');
    
    const span = {
      id: spanId,
      traceId,
      parentSpanId,
      name,
      service: this.serviceName,
      startTime: performance.now(),
      endTime: null,
      duration: null,
      tags: {},
      logs: []
    };
    
    this.spans.set(spanId, span);
    return spanId;
  }
  
  endSpan(spanId, status = 'OK') {
    const span = this.spans.get(spanId);
    if (!span) return;
    
    span.endTime = performance.now();
    span.duration = span.endTime - span.startTime;
    span.status = status;
    
    // Auto-export if this is a root span
    if (!span.parentSpanId) {
      this.exportSpan(span);
    }
    
    return span;
  }
  
  addTag(spanId, key, value) {
    const span = this.spans.get(spanId);
    if (span) {
      span.tags[key] = value;
    }
  }
  
  log(spanId, message, data = {}) {
    const span = this.spans.get(spanId);
    if (span) {
      span.logs.push({
        timestamp: new Date().toISOString(),
        message,
        data: JSON.stringify(data)
      });
    }
  }
  
  exportSpan(span) {
    // In a real application, this would send the span to a tracing backend
    // like Jaeger, Zipkin, or AWS X-Ray
    console.log('Exporting span:', JSON.stringify(span, null, 2));
    
    // Clean up
    this.spans.delete(span.id);
  }
  
  exportSpans() {
    // Export any remaining spans that have ended
    for (const [id, span] of this.spans.entries()) {
      if (span.endTime) {
        this.exportSpan(span);
      }
    }
  }
  
  injectContext(spanId, headers = {}) {
    const span = this.spans.get(spanId);
    if (!span) return headers;
    
    return {
      ...headers,
      'x-trace-id': span.traceId,
      'x-span-id': span.id,
      'x-service': this.serviceName
    };
  }
  
  extractContext(headers) {
    const traceId = headers['x-trace-id'] || crypto.randomBytes(16).toString('hex');
    const parentSpanId = headers['x-span-id'] || null;
    
    return { traceId, parentSpanId };
  }
}

// Usage example
const tracer = new Tracer('user-service');

// Simulate a request
function handleRequest(req) {
  const { traceId, parentSpanId } = tracer.extractContext(req.headers);
  const spanId = tracer.startSpan('handle-request', parentSpanId);
  
  tracer.addTag(spanId, 'http.method', req.method);
  tracer.addTag(spanId, 'http.url', req.url);
  
  // Simulate work
  setTimeout(() => {
    // Call another service
    const childSpanId = tracer.startSpan('call-auth-service', spanId);
    
    setTimeout(() => {
      tracer.endSpan(childSpanId, 'OK');
      
      // End the request
      tracer.endSpan(spanId, 'OK');
    }, 100);
  }, 50);
  
  return { status: 'processing', traceId };
}

// Simulate an incoming request
const request = {
  method: 'GET',
  url: '/api/users/123',
  headers: {}
};

const response = handleRequest(request);
console.log('Response:', response);

// Wait for spans to complete
setTimeout(() => {}, 200);
Misolni ishga tushirish »

Ishlashni optimallashtirish usullari

Node.js ilovasining ishlashini optimallashtirish uchun ilg‘or texnikalar:

1. CPU intensiv vazifalari uchun ishchi mavzular

Voqealar siklini blokirovka qilishning oldini olish uchun protsessor talab qiladigan operatsiyalarni ishchi oqimlarga yuklang:

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const { performance, PerformanceObserver } = require('perf_hooks');

if (isMainThread) {
  // Main thread
  function runWorker(data) {
    return new Promise((resolve, reject) => {
      const start = performance.now();
      
      const worker = new Worker(__filename, {
        workerData: data
      });
      
      worker.on('message', (result) => {
        const duration = performance.now() - start;
        resolve({
          ...result,
          duration: `${duration.toFixed(2)}ms`
        });
      });
      
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0) {
          reject(new Error(`Worker stopped with exit code ${code}`));
        }
      });
    });
  }
  
  // Example usage
  async function main() {
    try {
      const result = await runWorker({
        task: 'processData',
        data: Array(1000000).fill().map((_, i) => i)
      });
      
      console.log('Worker result:', result);
    } catch (err) {
      console.error('Worker error:', err);
    }
  }
  
  main();
} else {
  // Worker thread
  function processData(data) {
    // Simulate CPU-intensive work
    return data.map(x => Math.sqrt(x) * Math.PI);
  }
  
  try {
    const result = processData(workerData.data);
    parentPort.postMessage({
      task: workerData.task,
      resultLength: result.length,
      sample: result.slice(0, 5)
    });
  } catch (err) {
    parentPort.postMessage({ error: err.message });
  }
}
Misolni ishga tushirish »

2. Ma’lumotlarni samarali qayta ishlash

Katta hajmdagi ma’lumotlarni samarali qayta ishlash uchun streamlar va buferlardan foydalaning:

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

class ProcessingPipeline {
  constructor() {
    this.startTime = performance.now();
    this.processedItems = 0;
  }
  
  createTransformStream(transformFn) {
    return new Transform({
      objectMode: true,
      transform(chunk, encoding, callback) {
        try {
          const result = transformFn(chunk);
          this.processedItems++;
          callback(null, result);
        } catch (err) {
          callback(err);
        }
      }
    });
  }
  
  async processData(data, batchSize = 1000) {
    const batches = [];
    
    // Process in batches
    for (let i = 0; i < data.length; i += batchSize) {
      const batch = data.slice(i, i + batchSize);
      const processedBatch = await this.processBatch(batch);
      batches.push(processedBatch);
      
      // Log progress
      const progress = ((i + batchSize) / data.length * 100).toFixed(1);
      console.log(`Processed ${Math.min(i + batchSize, data.length)}/${data.length} (${progress}%)`);
    }
    
    return batches.flat();
  }
  
  processBatch(batch) {
    return new Promise((resolve) => {
      const results = [];
      
      // Create a transform stream for processing
      const processor = this.createTransformStream((item) => {
        // Simulate processing
        return {
          ...item,
          processed: true,
          timestamp: new Date().toISOString()
        };
      });
      
      // Collect results
      processor.on('data', (data) => {
        results.push(data);
      });
      
      processor.on('end', () => {
        resolve(results);
      });
      
      // Process each item in the batch
      for (const item of batch) {
        processor.write(item);
      }
      
      processor.end();
    });
  }
  
  getStats() {
    const endTime = performance.now();
    const duration = endTime - this.startTime;
    
    return {
      processedItems: this.processedItems,
      duration: `${duration.toFixed(2)}ms`,
      itemsPerSecond: (this.processedItems / (duration / 1000)).toFixed(2)
    };
  }
}

// Example usage
async function main() {
  // Generate test data
  const testData = Array(10000).fill().map((_, i) => ({
    id: i,
    value: Math.random() * 1000
  }));
  
  console.log('Starting data processing...');
  const pipeline = new ProcessingPipeline();
  
  // Process data in batches
  const result = await pipeline.processData(testData, 1000);
  
  // Print statistics
  console.log('Processing complete!');
  console.log('Statistics:', pipeline.getStats());
  console.log('Sample result:', result[0]);
}

main().catch(console.error);
Misolni ishga tushirish »

Ishlash testlarining eng yaxshi amaliyotlari

Ishlash testini o‘tkazishda quyidagi eng yaxshi amaliyotlarga amal qiling:

  1. Test in Production-Like Environments
    • Ishlab chiqarishga o‘xshash uskunadan foydalaning
    • Haqiqiy ma’lumotlar hajmini qo‘shing
    • Ishlab chiqarish trafigini simulyatsiya qilish
  2. Use Statistical Significance
    • Bir nechta sinov iteratsiyasini bajaring
    • Ishonch oraliqlarini hisoblang
    • To‘g‘ri ravishda chetga chiqqanlarni e’tiborsiz qoldiring
  3. Monitor System Resources
    • CPU va xotiradan foydalanishni kuzatib boring
    • Axlat yig‘ish jarayonini kuzatib boring
    • Xotira oqishiga e’tibor bering
  4. Profile Before Optimizing
    • Haqiqiy to‘siqlarni aniqlang
    • O‘zgarishlardan oldin va keyin o‘lchash
    • Yuqori ta’sirli optimallashtirishlarga e’tibor qarating


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!