Big O Notation: المفهوم اللي بيخلّيك تتنبأ بسرعة كودك قبل ما تشغّله أصلاً
مستوى المقال: مبتدئ
لو كتبت لوب اشتغل بسرعة على 100 عنصر، ده مش معناه إنه هيشتغل بسرعة على 100 ألف. الفرق بين كود بيخلّص في ثانية وكود بياخد 3 ساعات مش في عدد السطور، الفرق في حاجة اسمها Big O Notation. لو فهمتها مرة واحدة، هتبقى قادر تتنبأ بأداء أي كود قبل ما يلمس السيرفر.
المشكلة باختصار
كل مبرمج مبتدئ بيقع في نفس الفخ. بيكتب كود بيشتغل تمام على بيئة الـ development بـ 50 user، وأول ما الـ production يوصل لـ 10,000 user، الـ response time بيقفز لـ 8 ثواني والـ CPU بيقعد على 98%. السبب مش إن السيرفر ضعيف. السبب إن الكود نفسه مكتوب بطريقة بتزيد تكلفته الحسابية بشكل أُسّي مع زيادة البيانات. Big O Notation هي اللغة اللي بنوصف بيها التكلفة دي قبل ما تتحوّل لمشكلة فعلية في 3 الصبح.
مثال من الواقع: 3 طرق بتروح بيهم من بيتك للجامعة
قبل التعريف العلمي، خد سيناريو من حياتك اليومية. تخيّل إن في 3 طرق توصلك من بيتك للجامعة:
- الطريق الأول: طوله ثابت 5 كيلو مهما كانت الزحمة.
- الطريق الثاني: طوله بيزيد بنسبة عدد العربيات اللي قدامك. كل عربية بتضيف متر.
- الطريق الثالث: طوله بيتضاعف كل ما عدد العربيات يتضاعف، بسبب تقاطعات سيئة.
الصبح بدري وانت ماشي وحدك، الـ 3 طرق هيوصّلوك في 10 دقايق. الفرق ميظهرش. لكن وقت الذروة بـ 5,000 عربية في الشارع، الطريق الأول لسه 10 دقايق، الطريق الثاني هيبقى ساعة، الطريق الثالث هيبقى 14 ساعة.
ده بالظبط اللي بنوصفه بـ Big O. الطريق الأول رتبته O(1)، الثاني O(n)، الثالث O(n²). الفرق ما بيظهرش لما البيانات قليلة. بيظهر لما تكبر.
التعريف العلمي للـ Big O
Big O Notation هي طريقة رياضية لوصف معدّل نمو زمن التنفيذ (أو الذاكرة) لخوارزمية بالنسبة لحجم الدخل، حيث الـ n بتمثّل عدد العناصر اللي بتشتغل عليها. المرجع الأشهر في الموضوع، كتاب "Introduction to Algorithms" لـ Cormen و Leiserson و Rivest و Stein (المعروف بـ CLRS، الطبعة الرابعة 2022)، بيعرّفها في الفصل التالت صفحة 47 إنها بتمثّل "الحد الأعلى المُحكم" لمعدّل النمو لما n تروح للا نهاية.
الفكرة اللي يهمك تمسكها كمبتدئ: Big O مش بتقولك الكود ده هيخلّص في كام ثانية. بتقولك "لو ضاعفت البيانات، الزمن هيتصرّف ازاي؟".
أهم 5 رتب لازم تحفظهم
- O(1) - ثابت: الوصول لعنصر في array بـ index. السرعة واحدة سواء العنصر الأول أو رقم 9 مليون.
- O(log n) - لوغاريتمي: البحث الثنائي في array مرتّبة. كل خطوة بتقسّم البيانات نُص.
- O(n) - خطّي: المرور على كل عناصر list مرة واحدة.
- O(n log n) - شبه خطّي: خوارزميات الـ sorting الجيدة زي merge sort.
- O(n²) - تربيعي: nested loops، أو مقارنة كل عنصر بكل العناصر التانية.