تحليل أداء كود C#: العثور على الاختناقات في الممارسة العملية
\nيعد تحسين الأداء أحد المهام الأساسية للمطور. حتى أجمل كود يمكن أن يعمل ببطء إذا كان به اختناقات. في هذه المقالة، سننظر في كيفية تحليل أداء كود C# في بيئة .NET، والعثور على المناطق المشكلة، والقضاء عليها. ستتعرف على أدوات عملية مثل BenchmarkDotNet و dotMemory و Stopwatch المدمج، وستحصل أيضًا على أمثلة جاهزة للتحليل.
لماذا يعتبر تحليل الأداء مهمًا؟
\nتحليل الأداء لا يقتصر فقط على تشغيل تطبيق وقياس الوقت. إنه نهج منهجي لتحديد "الاختناقات": الخوارزميات البطيئة، تسربات الذاكرة، استعلامات قاعدة البيانات غير المثلى، أو التخصيصات المتكررة في الكومة. بدون تحليل الأداء، تخاطر بقضاء ساعات في تحسين أجزاء من الكود سريعة بالفعل، بينما تتجاهل المشكلات الحقيقية.
\n\n1. تحليل الأداء باستخدام Stopwatch (بداية سريعة)
\nأبسط طريقة لقياس وقت تنفيذ الكود هي استخدام الفئة System.Diagnostics.Stopwatch. إنها مناسبة للتقييم الأولي، ولكن ليس للمعايير الدقيقة بسبب تأثير ترجمة JIT والعمليات الخلفية.
مثال على استخدام Stopwatch
\nusing System.Diagnostics;\n\npublic class Example\n{\n public void Run()\n {\n Stopwatch sw = Stopwatch.StartNew();\n\n // Code to measure\n SimulateWork();\n\n sw.Stop();\n Console.WriteLine($"Execution time: {sw.ElapsedMilliseconds} ms");\n }\n\n private void SimulateWork()\n {\n for (int i = 0; i < 1_000_000; i++)\n {\n // Simulating work\n }\n }\n}\nالعيوب: لا يأخذ Stopwatch في الاعتبار إحماء JIT، أو جمع القمامة، أو عوامل أخرى. للتحليل الجاد، استخدم المكتبات المتخصصة.
\n\n2. تحليل الأداء الاحترافي باستخدام BenchmarkDotNet
\nBenchmarkDotNet هو المعيار الذهبي لقياس الأداء في .NET. يقوم تلقائيًا بتسخين الكود، وتشغيل تكرارات متعددة، وتحليل الإحصائيات، ومراعاة تأثير جامع القمامة. قم بتثبيت الحزمة عبر NuGet:
dotnet add package BenchmarkDotNet\n\nمثال على معيار مقارنة بين طريقتين
\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\n\npublic class StringBenchmark\n{\n private string[] data = { "apple", "banana", "cherry", "date" };\n\n [Benchmark]\n public string ConcatWithPlus()\n {\n string result = "";\n foreach (var s in data)\n result += s;\n return result;\n }\n\n [Benchmark]\n public string ConcatWithStringBuilder()\n {\n var sb = new System.Text.StringBuilder();\n foreach (var s in data)\n sb.Append(s);\n return sb.ToString();\n }\n}\n\npublic class Program\n{\n public static void Main()\n {\n var summary = BenchmarkRunner.Run<StringBenchmark>();\n }\n}\nبعد التشغيل، سترى جدولاً بالوقت وتخصيصات الذاكرة والأخطاء. يتيح لك هذا المقارنة الموضوعية بين StringBuilder والتسلسل باستخدام +.
3. تحليل الذاكرة باستخدام dotMemory وأدوات تشخيص Visual Studio
\nيمكن أن تحدث الاختناقات ليس فقط في السرعة ولكن أيضًا في استهلاك الذاكرة. تساعد أداة dotMemory من JetBrains وأدوات Visual Studio المدمجة (Diagnostic Tools) في العثور على التسريبات والتخصيصات المتكررة والكائنات التي تعيش طويلاً في الكومة.
كيفية استخدام أدوات تشخيص Visual Studio
\n- \n
- قم بتشغيل التطبيق في وضع Debug. \n
- افتح نافذة Diagnostic Tools (Debug → Windows → Show Diagnostic Tools). \n
- قم بتمكين تحليل الذاكرة (Memory Usage) أو تحليل وحدة المعالجة المركزية (CPU Usage). \n
- خذ لقطة للذاكرة (Snapshot) قبل وبعد تنفيذ الكود.