هذا المقال للمبتدئ.
لو كتبت دالة بتدوّر على اسم في array من 1000 عنصر وشغّلتها في 0.3 مللي ثانية، يبدو إن الكود ممتاز. لما الـ array يكبر لمليون عنصر، نفس الدالة بتاخد 5 دقائق. المشكلة مش في السيرفر، ولا في لغة البرمجة. المشكلة في حاجة اسمها Big O Notation، ولو ما فهمتهاش هتلاقي نفسك بتدفع فاتورة سيرفر أكبر بدون أي مكسب فعلي.
المشكلة باختصار
الكود اللي شغّال على بياناتك الحالية مش بالضرورة هيشتغل لما البيانات تكبر 1000 مرة. Big O بترسملك علاقة الزمن بحجم الإدخال قبل ما تكتشف الكارثة في الإنتاج. وده الفرق بين مهندس بيكتب كود "بيشتغل دلوقتي" ومهندس بيكتب كود "هيفضل شغّال لما الشركة تكبر".
لما البحث بقى ساعة بدل ثانية: ابدأ بالقصة الأبسط
افتكر لما كنت بتدوّر على رقم تليفون في كشكول قديم فيه 50 اسم. كنت بتفتح صفحة، تبص، وتقفلها لو الاسم مش هنا. أقصى عدد محاولات: 50. ممل، بس قابل للتنفيذ.
دلوقتي تخيّل نفس الطريقة على دفتر فيه 10 ملايين اسم. هتقعد أسبوع كامل لو ما لقيتش الاسم في النص الأول. لكن لو الأسماء مرتبة أبجدياً، بتفتح النص، تشوف أول حرف، تقرر تقفل النص الشمال ولا اليمين. في 24 ضغطة بس بتلاقي اسمك في 10 مليون.
الفرق بين 10 مليون خطوة و 24 خطوة هو بالظبط اللي Big O Notation بيقيسه. الطريقة الأولى O(n)، التانية O(log n). نفس البيانات، نفس الإجابة، فرق في عدد الخطوات بحوالي 416,000 ضعف.
التعريف العلمي الدقيق لـ Big O
Big O Notation هي طريقة رياضية لوصف سلوك دالة لما الإدخال يكبر لانهائياً. بتقولك: لو ضاعفت حجم البيانات، الزمن هيكبر إزاي.
التعريف الرسمي من علم تحليل الخوارزميات (Cormen, Leiserson, Rivest, Stein. Introduction to Algorithms, 4th ed., MIT Press, 2022): دالة f(n) بتتكتب O(g(n)) لو فيه ثوابت موجبة c و n₀ بحيث f(n) ≤ c·g(n) لكل n ≥ n₀.
ركز في الجملة دي: Big O بيقيس معدل النمو، مش الزمن المطلق. مش هيقولك الكود بياخد 0.3 مللي ثانية، هيقولك "لو ضاعفت الإدخال، الزمن هيتضاعف" أو "هيتربّع". الفرق بين الكلمتين دول هو الفرق بين كود بيشتغل وكود بيقع.
الترتيبات الخمسة اللي لازم تعرفها كمبتدئ
- O(1) — ثابت. الوصول لعنصر في array بـ index، أو get من hash table. مفيش علاقة بحجم البيانات.
- O(log n) — لوغاريتمي. البحث الثنائي في array مرتب. كل خطوة بتقسم البيانات على 2.
- O(n) — خطّي. البحث الكلاسيكي في array غير مرتب. الزمن بيتضاعف لما البيانات تتضاعف.
- O(n log n) — شبه خطّي. الترتيب الجيد زي mergesort و timsort.
- O(n²) — تربيعي. الـ nested loops البدائية. لما البيانات تتضاعف، الزمن بيتربّع.
تخيّل البيانات بتكبر من 1000 لـ مليون. هتلاقي:
- O(1): نفس الزمن (مللي ثانية)
- O(log n): من 10 خطوات لـ 20 خطوة