Node.js / المتقدم: خدمات Node.js موثوقة / الدرس 15
تجارب الأداء وميزانيات الذاكرة
حسّن الاختناقات المقاسة ببنى بيانات محدودة وتجارب تحافظ على صحة النتائج.
في هذه الصفحة
أهداف الدرس
- اشرح المفاهيم والمفاضلات المتعلقة بموضوع «تجارب الأداء وميزانيات الذاكرة».
- توقع المثالين وتحقق من مخرجاتهما وسلوك تنظيف الموارد فيهما.
- شخّص الإخفاقات الثلاثة الشائعة وطبق الحلول المشروحة على مدخلات مشابهة.
تحديد معنى التحسن
يحتاج التحسين إلى هدف وحمل محدد. قد يرتفع معدل الطلبات ويسوء زمن الذيل أو تنمو الذاكرة بلا قبول. حدد الرتبة الزمنية ومعدل الخطأ والإنتاجية وميزانية الموارد قبل التغيير. أدخل الإحماء وتوزيع مدخلات واقعي وقارن ظروف تشغيل متكافئة. لا تمثل تجربة الحاسوب المصغرة انتظار الشبكة وتنافس القاعدة وحدود الحاوية. أكد أولا استهلاك الشيفرة زمنا مهما في تحليل ممثل؛ فقد يسرع مساعد تافه معيارا دون تحسين الخدمة.
تغيير مقدار العمل
تغلب اختيارات الخوارزمية والوصول إلى البيانات تحسينات الصياغة غالبا. قد يجعل البحث الخطي المتكرر داخل حلقة الكلفة تربيعية؛ ويجعل بناء Map البحث مباشرا مقابل ذاكرة وإعداد إضافيين. يبني المثال الأول فهرسا لمنتجات اصطناعية ويحسب المجموع دون تكرار البحث. تحتاج المعرفات المكررة إلى سياسة لأن Map تحتفظ بالأخير عادة. يجب حفظ معاني العمل والترتيب والعناصر الغائبة والدقة والأخطاء. النتيجة الخاطئة الأسرع تراجع لا تحسين.
تقييد كل ذاكرة تخزين مؤقت
تقايض الذاكرة المؤقتة الحساب أو الإدخال والإخراج بذاكرة محتفظ بها واحتمال تقادم. حدد نطاق المفتاح وحد العناصر أو البايتات والإخلاء والانتهاء والإبطال قبل إضافتها. ينفذ المثال الثاني مخزنا تعليميا محدودا للأقل استخداما حديثا بترتيب Map. تجدد get الحداثة ويطرد العنصر الثالث الأقدم. القيم نصوص صغيرة؛ ويحتاج المخزن الحقيقي إلى ميزانية بايتات لأن عنصرين قد يحتويان جيجابايتات. لا تخلط المستخدمين أو المؤسسات في المفتاح عندما تغير الصلاحية النتيجة.
const products = [{ id: 'a', price: 3 }, { id: 'b', price: 5 }];
const index = new Map();
for (const product of products) {
if (index.has(product.id)) throw new Error('Duplicate product');
index.set(product.id, product);
}
const basket = [{ id: 'b', count: 2 }, { id: 'a', count: 1 }];
let total = 0;
for (const line of basket) {
const product = index.get(line.id);
if (!product) throw new Error('Missing product');
total += product.price * line.count;
}
console.log(total);
13
يخدم فهرس واحد كل عمليات البحث. يمنع سلوك التكرار والغياب الصريح تغير المعنى خفية.
فهم الاحتفاظ والتخصيص
يستعيد جامع الذاكرة الكائنات غير القابلة للوصول، لا التي انتهت الحاجة العملية إليها فقط. قد تحتفظ Map عامة أو مستمع أو إغلاق وعد أو مؤقت بالبيانات بلا نهاية. راقب الكومة عبر دورات حمل وخمول مماثلة بدلا من عد كل قفزة تسربا. تتضمن process.memoryUsage أبعادا خارج كومة JavaScript مثل المخازن الخارجية والذاكرة المقيمة. قد يقلل التدفق المدخل المحتفظ به، لكن التزامن والمخازن قد يضاعفان الاستخدام. قدّر كلفة الطلب وميزانية العملية وتحقق بالقياس.
class SmallCache {
constructor(limit) { if (!Number.isInteger(limit) || limit < 1) throw new Error('Invalid limit'); this.limit = limit; this.items = new Map(); }
get(key) {
if (!this.items.has(key)) return undefined;
const value = this.items.get(key); this.items.delete(key); this.items.set(key, value); return value;
}
set(key, value) {
this.items.delete(key); this.items.set(key, value);
if (this.items.size > this.limit) this.items.delete(this.items.keys().next().value);
}
}
const cache = new SmallCache(2);
cache.set('a', 'A'); cache.set('b', 'B'); cache.get('a'); cache.set('c', 'C');
console.log(cache.get('b'), cache.get('a'), cache.items.size);
undefined A 2
تجعل قراءة a العنصر b الأقل حداثة، فيطرده إدراج c مع حفظ حد العنصرين.
عرض التجربة بدقة
قارن تشغيلات متعددة واذكر التفاوت وحجم المدخل والبيئة. استخدم ساعة رتيبة مثل performance.now للمدة ولا تدخل كلفة التسجيل في المنطقة المقاسة. لا تجعل تسارعا ثابتا اختبار صحة لاختلاف الأجهزة والجدولة. تحقق من تساوي النتائج مستقلا ثم افحص توزيع الأزمنة والموارد. احتفظ بالتنفيذ الأبسط إذا كان التحسن ضئيلا أو زادت مخاطر الإبطال عن فائدته. يكتمل التحسين بتحسن النتيجة للمستخدم ضمن القيود المحددة.
الأخطاء الشائعة وإصلاحها
ينمو المخزن المؤقت بلا نهاية
- لماذا يحدث؟
- لم يُحدد إخلاء أو حد بايتات.
- كيف تصلحه؟
- أضف احتفاظا محدودا وإبطالا صريحا.
- كيف تتجنب تكراره؟
- راقب العناصر والبايتات والإصابات والنتائج القديمة.
المعيار أسرع والطلبات لم تتحسن
- لماذا يحدث؟
- لم يكن المساعد المحسن اختناق الخدمة.
- كيف تصلحه؟
- حلل مسار الطلب الممثل.
- كيف تتجنب تكراره؟
- حدد هدف المستخدم قبل التحسين.
تنخفض الكومة وتبقى الذاكرة المقيمة مرتفعة
- لماذا يحدث؟
- تجاهل التشخيص المخازن أو سلوك المخصص.
- كيف تصلحه؟
- افحص أبعاد الذاكرة والبيانات الخارجية المحتفظ بها.
- كيف تتجنب تكراره؟
- استخدم دورات حمل مماثلة وقياسات متعددة.
اختبر فهمك
1. يخزن مخزن من عنصرين مخزنين كل منهما500 ميجابايت. هل حد ذاكرته مناسب لعملية صغيرة؟
اعرض الحل المشروح
عدد العناصر محدود لكنه قد يحتفظ بنحو1 جيجابايت قبل الكلفة الأخرى. أضف ميزانية بايتات وارفض تخزين القيم الضخمة أو تجنبها. يجب ربط وحدة الحد بالمورد المحمي لا بطول المجموعة المريح فقط.
2. كيف تتحقق من حفظ السلوك عند استبدال البحث المتكرر بفهرس؟
اعرض الحل المشروح
قارن نتائج المدخل العادي والفارغ والمعرف الغائب والمكرر بعقد مستقل. افحص الترتيب والحساب قبل التوقيت، ثم قس أحمالا متكافئة تشمل بناء الفهرس؛ فإخفاء الإعداد قد يبالغ في التحسن.
أهم ما تعلمته
- يحتاج التحسين إلى هدف وحمل محدد.
- تغلب اختيارات الخوارزمية والوصول إلى البيانات تحسينات الصياغة غالبا.
- قارن تشغيلات متعددة واذكر التفاوت وحجم المدخل والبيئة.