تحسين أداء تطبيقات C#: للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا الأداء مهم من البداية؟

\n

كل مطور C# يواجه عاجلاً أم آجلاً موقفاً يبدأ فيه التطبيق بالتباطؤ. غالباً ما تُزرع مشاكل الأداء في المراحل المبكرة - بسبب الخوارزميات غير المثلى، أو التعامل غير الصحيح مع الذاكرة، أو الإفراط في استخدام LINQ دون فهم آلياته الداخلية. بالنسبة للمبتدئين، قد يبدو هذا الموضوع معقداً، لكن في الواقع المبادئ الأساسية للتحسين بسيطة بما يكفي ويمكن إتقانها في بضع ساعات من الممارسة.

\n

في هذه المقالة، سنناقش أربعة جوانب رئيسية ستساعدك على كتابة تطبيقات C# سريعة وفعالة على منصة .NET. ستتعلم كيفية تنميط الكود، تحسين استعلامات LINQ، إدارة الذاكرة بشكل صحيح، واستخدام البرمجة غير المتزامنة. ستكون أمثلة الكود قريبة قدر الإمكان من المهام الحقيقية التي يواجهها المطورون.

\n\n

1. التنميط: الخطوة الأولى نحو التحسين

\n

قبل تحسين أي شيء، تحتاج إلى فهم ما الذي يسبب التباطؤ بالضبط. التخمينات البديهية غالباً ما تكون خاطئة. التنميط هو عملية قياس أداء الكود الخاص بك باستخدام أدوات خاصة.

\n\n

أدوات التنميط

\n
    \n
  • Visual Studio Diagnostic Tools - أداة مدمجة متوفرة في إصدارات Community والإصدارات الأعلى. تتيح تتبع استخدام وحدة المعالجة المركزية والذاكرة ووقت التنفيذ.
  • \n
  • JetBrains dotMemory / dotTrace - أدوات تجارية قوية لتحليل الذاكرة ووقت التنفيذ.
  • \n
  • BenchmarkDotNet - مكتبة خفيفة الوزن للاختبارات المعيارية الدقيقة. مثالية لمقارنة تطبيقين لطريقة واحدة.
  • \n
\n\n

مثال: قياس وقت التنفيذ

\n

نستخدم Stopwatch لقياس بسيط:

\n
using System.Diagnostics;\n\nvar stopwatch = Stopwatch.StartNew();\n// الكود الخاص بك\nfor (int i = 0; i < 1000000; i++)\n{\n    // عملية ما\n}\nstopwatch.Stop();\nConsole.WriteLine($"وقت التنفيذ: {stopwatch.ElapsedMilliseconds} مللي ثانية");
\n

نصيحة: للقياسات الدقيقة، استخدم BenchmarkDotNet، لأن Stopwatch لا يأخذ في الاعتبار النفقات العامة لترجمة JIT.

\n\n

2. التعامل مع الذاكرة والسلاسل النصية

\n

إدارة الذاكرة في .NET آلية (جامع القمامة)، لكن هذا لا يعني أنه يمكنك تجاهلها. واحدة من أكثر المشاكل شيوعاً هي الإنشاء المفرط للسلاسل النصية.

\n\n

المشكلة: دمج السلاسل النصية في حلقة

\n

السلاسل النصية في C# غير قابلة للتغيير. كل عملية + تنشئ سلسلة نصية جديدة، مما يؤدي إلى تخصيصات مستمرة وضغط على GC:

\n
string result = "";\nfor (int i = 0; i < 10000; i++)\n{\n    result += i.ToString(); // سيء: يتم إنشاء 10000 سلسلة نصية جديدة\n}
\n\n

الحل: StringBuilder

\n

تعمل الفئة StringBuilder مع مخزن مؤقت للأحرف وتقلل من التخصيصات:

\n
var sb = new StringBuilder();\nfor (int i = 0; i < 10000; i++)\n{\n    sb.Append(i);\n}\nstring result = sb.ToString(); // جيد: تخصيص واحد في النهاية
\n\n

تجنب التغليف (Boxing)

\n

التغليف (تعبئة الأنواع القيمية في كائن) هو مصدر آخر للتخصيصات المخفية. مثال:

\n
ArrayList list = new ArrayList();\nlist.Add(42); // تغليف: يتم تعبئة int في object\n\n// الأفضل استخدام المجموعات العامة:\nList<int> list2 = new List<int>();\nlist2.Add(42); // بدون تغليف
\n\n

3. تحسين استعلامات LINQ

\n

LINQ أداة قوية، لكن استخدامها غير الصحيح يمكن أن يبطئ التطبيق بشكل كبير. المشكلة الرئيسية هي التكرارات المتعددة للمجموعات.

\n\n

المشكلة: التكرارات المتعددة

\n

كل استدعاء لـ Where() أو Select() أو Count() يمكن أن يعيد تكرار المجموعة من جديد إذا لم يتم تجسيد النتيجة:

\n
var numbers = Enumerable.Range(1, 1000000);\nvar evenNumbers = numbers.Where(n => n % 2 == 0);\nint coun                

المدونات

توصيات الكتب