مستوى المقال: مبتدئ. لو انت لسه بادئ في البرمجة وسمعت كلمة "Big-O" وحسيت إنها طلاسم، المقال ده ليك. هنشرحها بمثال بسيط الأول، وبعدين نرجع للتعريف العلمي الدقيق.
تعقيد الوقت Big-O: إزاي تعرف إن كودك هيبطأ قبل ما المشروع يكبر
هتكسب حاجة واحدة من المقال ده: هتبص على أي دالة وتعرف هتفضل سريعة ولا هتخنق لما البيانات تكبر، من غير ما تشغّلها أصلًا. دي أهم مهارة بتفرّق بين مبتدئ وبين حد بيكتب كود بيكبر.
المشكلة باختصار
الكود بتاعك بيشتغل تمام دلوقتي. عندك 100 مستخدم في قاعدة البيانات، والصفحة بتفتح في جزء من الثانية. بعد سنة بقى عندك مليون مستخدم، ونفس الصفحة بقت تاخد 30 ثانية. مفيش حاجة اتغيّرت في الكود، السيرفر نفسه، بس البيانات كبرت. المشكلة مش في السيرفر، المشكلة في إن الخوارزمية بتاعتك بتكبّر شغلها بسرعة أكبر من البيانات نفسها. Big-O هي اللغة اللي بتوصف ده بالظبط.
الأول بمثال: دليل التليفون
تخيّل معاك دليل تليفون ورقي فيه مليون اسم، مرتّبين أبجديًا. عايز تلاقي رقم "محمود".
- الطريقة الأولى: تفتح من أول صفحة وتقرأ اسم اسم لحد ما توصل. لو الاسم في الآخر، ممكن تقلّب مليون صفحة. ده اسمه O(n): الشغل بيزيد بنفس معدل زيادة البيانات. ضِعف الأسماء يعني ضِعف الوقت.
- الطريقة التانية: تفتح في النص، تبص الاسم اللي قدامك قبل ولا بعد "محمود"، وترمي نص الدليل اللي مالكش فيه، وتكرّر. مليون اسم بتخلص في حوالي 20 خطوة بس. ده اسمه O(log n): كل خطوة بتقسم المشكلة على 2.
الفرق؟ في المليون، الأولى 1,000,000 خطوة، والتانية 20 خطوة. نفس المشكلة، فرق 50 ألف ضعف. دي فكرة Big-O كلها في جملة: مش بتقيس الوقت بالثواني، بتقيس إزاي الوقت بيكبر مع البيانات.
دلوقتي التعريف العلمي
Big-O هي طريقة لوصف أسوأ حالة لنمو عدد العمليات في خوارزمية بالنسبة لحجم المدخل، اللي بنسمّيه n. إحنا بنتجاهل الثوابت والتفاصيل الصغيرة، وبنركّز على الشكل العام للنمو لما n تكبر جدًا. يعني O(2n) وO(n) بنعتبرهم واحد، لأن المهم إنهم بيكبروا خطيًا. الافتراض هنا إن n كبيرة كفاية عشان الفرق في شكل النمو يبقى هو اللي بيحكم، مش الأرقام الصغيرة.
أشهر 5 فئات لازم تحفظها
- O(1) ثابت: نفس عدد الخطوات مهما كبرت البيانات. مثال: الوصول لعنصر في قائمة برقمه
arr[5]. - O(log n) لوغاريتمي: بيكبر ببطء شديد. مثال: البحث الثنائي.
- O(n) خطي: بيكبر بنفس معدل البيانات. مثال: المرور على كل عنصر مرة.
- O(n log n): أفضل ما يمكن لخوارزميات الترتيب العامة زي
sort(). - O(n²) تربيعي: حلقة جوّه حلقة. مثال: مقارنة كل عنصر بكل عنصر. ده بيقتل الأداء بسرعة.
جرّبها بنفسك بالأرقام
الكلام النظري مش كفاية. الكود ده بيقيس الفرق فعليًا بين O(n) وO(n²) وO(1) على نفس البيانات: