Performance Hooks என்றால் என்ன?
perf_hooks தொகுதி W3C Performance Timeline விவரக்குறிப்பின் அடிப்படையில் செயல்திறன் அளவீட்டிற்கான APIகளின் தொகுப்பை வழங்குகிறது.
இந்த கருவிகள் பின்வருவனவற்றிற்கு அத்தியாவசியமானவை:
குறிப்பிட்ட செயல்பாடுகளின் நேரத்தை அளவிடுதல்
வெவ்வேறு செயல்பாடுகள் எடுக்கும் நேரத்தை துல்லியமாக அளவிடுதல்
செயல்திறன் தடைகளைக் கண்டறிதல்
பயன்பாட்டில் மெதுவாக செயல்படும் பகுதிகளை அடையாளம் காணுதல்
வெவ்வேறு செயல்படுத்தல்களின் செயல்திறனை ஒப்பிடுதல்
வெவ்வேறு அல்காரிதம் செயல்படுத்தல்களின் செயல்திறனை ஒப்பிடுதல்
காலப்போக்கில் பயன்பாட்டு செயல்திறனைக் கண்காணித்தல்
பயன்பாட்டின் செயல்திறன் மாற்றங்களை காலப்போக்கில் கண்காணித்தல்
இந்த தொகுதி உயர்-ரெசல்யூஷன் டைமர்கள், செயல்திறன் மார்க்குகள், அளவீடுகள், கண்காணிப்பாளர்கள் மற்றும் ஹிஸ்டோகிராம்கள் போன்ற பல பயனுள்ள அம்சங்களை உள்ளடக்கியது.
Performance Hooks தொகுப்பைப் பயன்படுத்துதல்
Performance Hooks தொகுப்பைப் பயன்படுத்த, உங்கள் குறியீட்டில் அதை தேவைப்படுத்த வேண்டும்:
// Import the entire module
const { performance, PerformanceObserver } = require('perf_hooks');
// Or using destructuring for specific parts
const { performance } = require('perf_hooks');
அடிப்படை நேர அளவீடு
செயல்திறன் API இன் மிக அடிப்படை பயன்பாடு உயர் துல்லியத்துடன் கடந்து செல்லும் நேரத்தை அளவிடுவதாகும்:
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`);
குறிப்பு:
performance.now() முறை தற்போதைய Node.js செயல்முறை தொடங்கிய நேரத்திலிருந்து அளவிடப்பட்ட மில்லி விநாடிகளில் உயர்-ரெசல்யூஷன் டைம்ஸ்டாம்பை வழங்குகிறது.
செயல்திறன் மார்க்குகள் மற்றும் அளவீடுகள்
மார்க்குகள்
செயல்திறன் மார்க்குகள் நீங்கள் கண்காணிக்க விரும்பும் குறிப்பிட்ட நேர புள்ளிகள்:
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'));
அளவீடுகள்
செயல்திறன் அளவீடுகள் இரண்டு மார்க்குகளுக்கு இடையே உள்ள நேர கால அளவைக் கணக்கிடுகின்றன:
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();
செயல்திறன் கண்காணிப்பாளர்
PerformanceObserver செயல்திறன் நிகழ்வுகளை அசின்க்ரோனஸாக கண்காணிக்க உங்களை அனுமதிக்கிறது:
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);
செயல்திறன் டைம்லைன் API
செயல்திறன் டைம்லைன் API செயல்திறன் உள்ளீடுகளை மீட்டெடுக்க முறைகளை வழங்குகிறது:
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'));
செயல்திறன் டைமிங் நிலைகள்
Node.js மாறுபட்ட அளவிலான துல்லியத்துடன் வெவ்வேறு செயல்திறன் டைமிங் APIகளை வழங்குகிறது:
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);
நிகழ்வு வளைய கண்காணிப்பு
monitorEventLoopDelay செயல்பாடு நிகழ்வு வளையில் உள்ள தாமதத்தை கண்காணிக்க ஒரு வழியை வழங்குகிறது:
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`);
});
});
குறிப்பு:
நீண்ட-இயக்கும் பணிகள் நிகழ்வு வளையத்தைத் தடுப்பதால் உங்கள் பயன்பாடு பதிலளிப்புத் தன்மையில் சிக்கல்களை அனுபவிக்கும் போது கண்டறிய நிகழ்வு வளைய கண்காணிப்பு குறிப்பாக பயனுள்ளதாக இருக்கும்.
அசின்க்ரோனஸ் செயல்பாடுகளில் செயல்திறன் கண்காணிப்பு
அசின்க்ரோனஸ் செயல்பாடுகளில் செயல்திறனைக் கண்காணிப்பதற்கு கவனமான மார்க் வைப்பு தேவைப்படுகிறது:
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);
});
வாக்குறுதிகளைக் கண்காணித்தல்
வாக்குறுதிகளின் செயல்திறனை அளவிடுவதற்கு ஒத்த நுட்பங்கள் தேவைப்படுகின்றன:
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();
});
செயல்திறன் டைமிங் எச்சரிக்கைகள்
செயல்திறன் APIகளைப் பயன்படுத்தும் போது, சில எச்சரிக்கைகளை அறிந்து கொள்ளுங்கள்:
டைமிங் ரெசல்யூஷன்
டைமிங் ரெசல்யூஷன் பிளாட்ஃபார்ம்களுக்கு இடையே வேறுபடுகிறது
கிளாக் டிரிஃப்ட்
நீண்ட-இயக்கும் செயல்முறைகளில் கிளாக் டிரிஃப்ட் ஏற்படலாம்
பேக்குரவுண்ட் செயல்பாடு
பேக்குரவுண்ட் செயல்பாடு டைமிங் அளவீடுகளை பாதிக்கலாம்
JIT தொகுப்பு
JavaScript JIT தொகுப்பு சீரற்ற முதல்-இயக்க நேரங்களை ஏற்படுத்தும்
எடுத்துக்காட்டு: துல்லியமான பேன்ச்மார்க்கிங்
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`);
NodeJS Performance Hooks vs Browser Performance API
Node.js Performance Hooks API W3C Performance Timeline விவரக்குறிப்பின் அடிப்படையில் உள்ளது, ஆனால் பிரௌசரின் Performance API உடன் ஒப்பிடும்போது சில வேறுபாடுகள் உள்ளன:
| அம்சம் | பிரௌசர் Performance API | Node.js Performance Hooks |
|---|---|---|
| நேர தோற்றம் | பக்கம் வழிசெலுத்துதல் தொடக்கம் | செயல்முறை தொடக்க நேரம் |
| வள டைமிங் | கிடைக்கும் | பயன்படுத்த முடியாது |
| வழிசெலுத்துதல் டைமிங் | கிடைக்கும் | பயன்படுத்த முடியாது |
| பயனர் டைமிங் (மார்க்/அளவீடு) | கிடைக்கும் | கிடைக்கும் |
| உயர்-ரெசல்யூஷன் நேரம் | கிடைக்கும் | கிடைக்கும் |
| நிகழ்வு வளைய கண்காணிப்பு | வரையறுக்கப்பட்ட | கிடைக்கும் |
நடைமுறை எடுத்துக்காட்டு: API செயல்திறன் கண்காணிப்பு
API எண்ட்பாயிண்டுகளைக் கண்காணிக்க செயல்திறன் கூடுகளைப் பயன்படுத்துவதற்கான ஒரு நடைமுறை எடுத்துக்காட்டு:
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}`);
});
மேம்பட்ட செயல்திறன் கண்காணிப்பு
உற்பத்தி-தர பயன்பாடுகளுக்கு, இந்த மேம்பட்ட கண்காணிப்பு நுட்பங்களைக் கவனியுங்கள்:
1. நினைவக கசிவு கண்டறிதல்
செயல்திறன் கூடுகள் மற்றும் Node.js நினைவக கண்காணிப்பைப் பயன்படுத்தி நினைவக கசிவுகளைக் கண்டறிந்து பகுப்பாய்வு செய்யுங்கள்:
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);
குறிப்பு:
நினைவக கசிவு கண்டறிதல் எடுத்துக்காட்டிற்கு heapdump பேக்கேஜ் தேவைப்படுகிறது. npm install heapdump ஐப் பயன்படுத்தி அதை நிறுவவும்.
2. தனிப்பயன் செயல்திறன் அளவீடுகள்
விரிவான டைமிங் தகவலுடன் தனிப்பயன் செயல்திறன் அளவீடுகளை உருவாக்கி கண்காணிக்கவும்:
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);
செயல்திறன் கூடுகளுடன் விநியோகிக்கப்பட்ட ட்ரேசிங்
செயல்திறன் கூடுகளைப் பயன்படுத்தி மைக்ரோசர்விஸ்கள் முழுவதும் விநியோகிக்கப்பட்ட ட்ரேசிங்கை செயல்படுத்துங்கள்:
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);
செயல்திறன் உகப்பாக்க நுட்பங்கள்
Node.js பயன்பாட்டு செயல்திறனை உகப்பாக்குவதற்கான மேம்பட்ட நுட்பங்கள்:
1. CPU-தீவிர பணிகளுக்கான தொழிலாளர் நூல்கள்
நிகழ்வு வளையத்தைத் தடுப்பதைத் தடுக்க CPU-தீவிர செயல்பாடுகளை தொழிலாளர் நூல்களுக்கு இடமாற்றம் செய்யுங்கள்:
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 });
}
}
2. திறமையான தரவு செயலாக்கம்
திறமையான பெரிய தரவு செயலாக்கத்திற்கு ஸ்ட்ரீம்கள் மற்றும் பஃபர்களைப் பயன்படுத்துங்கள்:
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);
செயல்திறன் சோதனை சிறந்த நடைமுறைகள்
செயல்திறன் சோதனையை நடத்தும் போது, இந்த சிறந்த நடைமுறைகளைப் பின்பற்றவும்: