مستوى المقال: مبتدئ
لو كودك بيشتغل تمام على 100 عنصر وبيتعلق ساعة كاملة على 100 ألف عنصر، المشكلة مش في السيرفر ومش في اللغة. المشكلة في حاجة اسمها Big O Notation. ولو فهمتها صح، هتعرف من غير ما تشغّل الكود إذا كان هيقعد ثانية ولا يوم كامل.
المقال ده هيشرحلك Big O من الصفر. هتطلع بفهم عملي تقدر تستخدمه في الـ code review بكرة الصبح، مش مجرد كلام نظري في الجامعة.
المشكلة باختصار
لما بتكتب كود وبتجرّبه على بيانات صغيرة، كل حاجة بتبان حلوة. بس البيانات الحقيقية بتبدأ صغيرة وبتكبر. المستخدمين بيزيدوا، الجدول في قاعدة البيانات بيوصل لمليون صف، الـ API بتاعتك بتدخلها 10 آلاف طلب في الدقيقة بدل 100.
اللي بيحصل فعلاً إن في فرق هائل بين كود بياخد وقت ثابت وكود بياخد وقت بيتضاعف مع البيانات. وده اللي Big O بيقيسه.
مثال بسيط جداً: تدوّر على رقم تليفون صاحبك
تخيّل إن عندك دفتر تليفونات ورقي فيه 1000 اسم، عايز تلاقي رقم صاحبك "أحمد".
الطريقة الأولى: تفتح الدفتر من أوله وتبص اسم اسم لحد ما تلاقيه. لو "أحمد" في أول الدفتر، هتلاقيه بسرعة. لو في آخره، هتقرا 1000 اسم. ده اسمه Linear Search.
الطريقة الثانية: الدفتر مرتب أبجديًا. تفتحه في النص. لو الصفحة فيها حرف "ر"، يبقى "أحمد" في النصف الأول. تتجاهل النصف التاني كله وتفتح في نص النص الأول. وهكذا. بعد 10 خطوات تقريبًا تكون لقيته. ده اسمه Binary Search.
بالظبط ده الفرق اللي Big O بيوصفه. الطريقة الأولى لو الدفتر كبر لمليون اسم، ممكن تقرا مليون اسم. الطريقة التانية لو الدفتر كبر لمليون اسم، بتقرا 20 اسم بس. الفرق بين عمر كامل وكوبايتين شاي.
تعريف Big O بطريقة علمية ودقيقة
Big O Notation هي طريقة رياضية لوصف كيف يتغيّر زمن تنفيذ الخوارزمية مع زيادة حجم المدخلات. بمعنى أدق: هي تصف الحد الأعلى (upper bound) لمعدل النمو في أسوأ حالة.
بنكتبها بصيغة O(f(n)) حيث:
n= حجم المدخلات (عدد العناصر، طول النص، عدد الصفوف).f(n)= الدالة اللي بتوصف معدل النمو.
المهم إن Big O بتتجاهل الثوابت والعوامل الصغيرة. خوارزمية بتاخد 3n + 5 ثانية، Big O بتاعتها O(n). ليه؟ لأن لما n بتكبر جدًا، الـ 3 والـ 5 بيبقوا تافهين.
أشهر 6 درجات تعقيد لازم تعرفهم
دي القايمة مرتبة من الأسرع للأبطأ. احفظها كأنها جدول الضرب:
- O(1) — زمن ثابت: الكود بياخد نفس الوقت بغض النظر عن حجم البيانات. مثال: قراءة عنصر من Array بالـ index.
- O(log n) — زمن لوغاريتمي: الزمن بيزيد ببطء جدًا حتى مع بيانات ضخمة. مثال: Binary Search.
- O(n) — زمن خطي: الزمن بيزيد بنفس نسبة زيادة البيانات. مثال: Loop واحدة على Array.
- O(n log n) — أفضل ما يمكن للترتيب: أسرع خوارزميات الترتيب الشائعة. مثال: Merge Sort, Quick Sort.