C# تحت الغطاء: كيفية تسريع الكود باستخدام التنميط

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

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

ابدأ الدورة

تطبيق C# الخاص بك بطيء؟ حان الوقت للنظر تحت الغطاء



لقد كتبت كودًا جميلاً نظيفًا بلغة C#، لكنه يعمل بشكل أبطأ مما ترغب. هل هذا مألوف؟ في التطوير الحديث، غالبًا ما يصبح أداء C# عاملاً حاسمًا: المستخدمون لا يغفرون أوقات التحميل الطويلة، ويجب أن تتحمل تطبيقات الخادم آلاف الطلبات في الثانية. الخبر السار: يوفر .NET أدوات قوية لـ تشخيص .NET وتنميط C#. الخبر السيئ: بدون فهم العملية، فإنك تخاطر بتحسين ما لا يحتاج إلى تحسين.



في هذه المقالة، سنشرح كيفية تنميط كود C# بشكل صحيح، والعثور على نقاط الاختناق الحقيقية في C#، وتطبيق تقنيات مثبتة لـ تحسين كود C#. ستتعلم لماذا غالبًا ما تكون التخمينات البديهية خاطئة، وكيفية استخدام BenchmarkDotNet وتتبع ETW للحصول على بيانات موضوعية. هيا بنا!



لماذا "بالتخمين" لا يعمل: خرافات حول التحسين



قبل أن تبدأ في تحسين كود C#، دعنا نبدد المفاهيم الخاطئة الشائعة. يعتقد العديد من المطورين أنهم يعرفون أين يبطئ برنامجهم. في الواقع، يُظهر تنميط C#: 90% من الوقت يذهب إلى 10% من الكود، وهذه "النقاط الساخنة" غالبًا ما تكون في أماكن غير متوقعة.



الأخطاء النموذجية:

  • التحسين المبكر — تقضي ساعات في تسريع أجزاء يتم تنفيذها مرة واحدة في اليوم.
  • الثقة في الحدس — "استعلام LINQ هذا بالتأكيد بطيء" (بينما المشكلة الحقيقية في التسلسل).
  • تجاهل GC — يمكن لمجمع القمامة أن يستهلك ما يصل إلى 30% من وقت المعالج إذا كنت تدير الذاكرة بشكل غير صحيح.


الخلاصة: يجب قياس أداء C#، وليس تخمينه. لهذا الغرض، توجد أدوات احترافية.



مجموعة أدوات تنميط C#



في نظام .NET البيئي، هناك عدة طرق لـ تشخيص .NET. دعنا نستعرض الأساسيات.



BenchmarkDotNet — أفضل صديق لك



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



مثال: لنقارن حلقة for العادية مع foreach لمصفوفة:



using BenchmarkDotNet.Attributes;using BenchmarkDotNet.Running;

[MemoryDiagnoser] // قياس تخصيص الذاكرةpublic class LoopBenchmarks{ private int[] _data;

[GlobalSetup] public void Setup() { _data = Enumerable.Range(0, 1000).ToArray(); }

[Benchmark] public int ForLoop() { int sum = 0; for (int i = 0; i < _data.Length; i++) sum += _data[i]; return sum; }

[Benchmark] public int ForeachLoop() { int sum = 0; foreach (var item in _data) sum += item; return sum; }}

class Program{ static void Main() => BenchmarkRunner.Run<LoopBenchmarks>();}


بتشغيل هذا الكود، سترى أن أداء C# لـ foreach على المصفوفات مطابق لـ for — يقوم JIT بتحسين كلا الخيارين بنفس الطريقة. ولكن بالنسبة لـ List<T>، قد يكون foreach أبطأ بسبب فحوصات الحدود.



مُنمّطات Visual Studio و dotMemory



لـ تنميط C# كامل على مستوى التطبيق، استخدم المُنمّط المدمج في Visual Studio (متوفر في إصدار Enterprise) أو dotMemory المجاني من JetBrains. سيعرضان:

  • أي الدوال تستهلك أكبر قدر من وحدة المعالجة المركزية.
  • كمية الذاكرة المخصصة و

المدونات

توصيات الكتب