أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

Big O Notation للمبتدئ: ليه كودك يشتغل في 0.1 ثانية على 100 عنصر و10 ثواني على 10K

📅 ١١ مايو ٢٠٢٦⏱ 5 دقائق قراءة
Big O Notation للمبتدئ: ليه كودك يشتغل في 0.1 ثانية على 100 عنصر و10 ثواني على 10K

هذا المقال يتطلب مستوى مبتدئ

لو كتبت دالة بحث بتشتغل بسرعة على 100 عنصر، وفجأة بتاخد 10 ثواني لما العدد يبقى 10,000، المشكلة مش في السيرفر ولا في اللغة. المشكلة في "شكل النمو" بتاع الكود نفسه. Big O Notation هي اللغة اللي بتقولك ده قبل ما تكتشفه على الإنتاج.

Big O Notation: قياس الكود قبل ما يكسر

شاشة لاب توب تعرض كود JavaScript بيقيس زمن تنفيذ خوارزميات بحث مختلفة الأداء

المشكلة باختصار

كتير من المطورين بيقيسوا الأداء بمعادلة "اشتغل ولا لأ". المعادلة دي بتنفع وانت لسه شغّال على 50 سجل في local DB. لما العدد يطلع 50 ألف، الكود اللي كان "شغّال" بيبقى الـ bottleneck الأول في الـ pipeline. Big O بترد على سؤال مختلف: لو حجم المدخل كبر 10 مرات، الزمن هيكبر كام مرة؟

ابدأ بمثال يومي قبل أي كلام تقني

تخيّل إنك بتدوّر على اسم في دفتر تليفونات ورقي فيه 1000 رقم.

  • الطريقة الأولى: بتفتح صفحة صفحة من الأول للآخر لحد ما تلاقي الاسم. لو الاسم في آخر صفحة، انت قريت 1000 صفحة.
  • الطريقة الثانية: بتفتح في النص، بتشوف الاسم اللي بتدوّر عليه قبل ولا بعد الصفحة دي أبجدياً، بتاخد النص اللي فيه الاسم، وبتفضل تنصّف. في الحالة دي مش هتقرا أكتر من 10 صفحات تقريباً.

الطريقة الأولى بتسمى O(n)، والثانية بتسمى O(log n). الفرق مش "أسرع شوية" — الفرق إن لو الدفتر بقى مليون رقم، الطريقة الأولى هتاخد مليون خطوة، والثانية حوالي 20 خطوة فقط.

التعريف العلمي بعد ما المثال وصل

Big O Notation هي صيغة رياضية بتوصف الحد الأقصى لنمو عدد العمليات اللي بيعملها الكود مع كبر حجم المدخلات. الـ "n" بتعني حجم المدخل، والصيغة بتركّز على المعامل الأهم في معادلة النمو، وبتتجاهل الثوابت والمعاملات الأقل تأثيراً.

يعني لو دالة بتعمل 3n² + 5n + 100 عملية، Big O بتاعتها O(n²)، لأن n² هو اللي بيتحكم في النمو لما n تكبر.

أنواع التعقيد الشائعة بترتيب السرعة

اللي فوق أسرع. اللي تحت بيقتل الإنتاج.

  1. O(1) — Constant Time: الكود بياخد نفس الوقت بغض النظر عن حجم المدخل. مثال: قراءة عنصر من Array بالـ index، أو فحص قيمة في HashMap.
  2. O(log n) — Logarithmic: بينصّف المشكلة كل تكرار. Binary search على مصفوفة مرتبة، أو البحث في Binary Tree متوازن.
  3. O(n) — Linear: بيعدّي على كل عنصر مرة واحدة. مثال: Array.indexOf() أو حساب مجموع عناصر.
  4. O(n log n): أسرع خوارزميات الترتيب الشائعة (Merge Sort, Quick Sort في المتوسط).
  5. O(n²) — Quadratic: نسيت for جوا for على نفس البيانات. على 10K عنصر، ده 100 مليون عملية.
  6. O(2ⁿ) — Exponential: كل عنصر زيادة بيضاعف الزمن. حلول recursion لـ Fibonacci بدون memoization بتقع هنا.
رسم بياني يوضح منحنيات النمو لتعقيدات Big O المختلفة من O(1) إلى O(n²) مع زيادة حجم المدخلات

كود JavaScript شغّال يوضّح الفرق

شوف الفرق بين O(n²) و O(n) في مهمة بسيطة: العثور على القيم المكرّرة في array.

JavaScript
// O(n²) - الطريقة البديهية الغلط
function findDuplicatesSlow(arr) {
  const dups = [];
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) dups.push(arr[i]);
    }
  }
  return dups;
}

// O(n) - باستخدام Set
function findDuplicatesFast(arr) {
  const seen = new Set();
  const dups = new Set();
  for (const v of arr) {
    if (seen.has(v)) dups.add(v);
    seen.add(v);
  }
  return [...dups];
}

قياس فعلي على Node.js 22، Array بـ 100,000 عنصر random:

  • findDuplicatesSlow: 8,420ms (8.4 ثانية)
  • findDuplicatesFast: 14ms

الفرق 600 ضعف بنفس المنطق. اللي اتغيّر هو شكل النمو، مش السرعة المطلقة للـ CPU.

Trade-offs لازم تنتبه لها

  • Big O بتقيس الأسوأ، مش المتوسط. Quick Sort O(n log n) في المتوسط، لكن O(n²) في أسوأ حالة. لو بياناتك مرتّبة جزئياً، التقدير ممكن يخدعك.
  • الثوابت بتتجاهل، بس بتفرق على n صغيرة. خوارزمية O(n) معاملها 1000 ممكن تكون أبطأ من O(n²) معاملها 0.1 لما n = 50.
  • Big O مش بتقيس الذاكرة. الحل السريع فوق بياخد ذاكرة إضافية O(n) في Set. لو السيرفر RAM بتاعه 512MB والـ array فيها 10M عنصر، الحل ده ممكن يقع.
  • القراءة لها قيمة. كود O(n²) أوضح ممكن يكون أحسن من O(n) معقّد لو الـ n عمرها مش هتعدي 100.

متى Big O مش مهمة

  • لو n ثابتة وصغيرة (عدد أيام الأسبوع، عدد HTTP methods). nested loop على 7 عناصر مش مشكلة.
  • لو الكود بيشتغل مرة واحدة في الـ startup مش في الـ hot path.
  • لو الـ bottleneck الحقيقي في I/O (DB, network) مش في CPU. أسرع خوارزمية في الدنيا مش هتنفعك لو السطر اللي قبلها بيستنى DB query مدته 800ms.

اللي بيحصل فعلاً في الإنتاج: 80% من مشاكل الأداء بتيجي من O(n²) مدسوسة في loops، و20% من DB queries غير مفهرسة. ابدأ منهم.

الخطوة التالية

افتح أي function في الكود بتاعك بتاخد أكتر من 200ms لما البيانات تكبر. عدّ عدد الـ loops المتداخلة. لو لقيت for جوا for بيلفّ على نفس الـ array، احتمال 70% إن دي مكان الـ O(n²). بدّلها بـ Set أو Map. لو زمن الاستجابة نزل أقل من 50ms، انت فهمت Big O بالظبط.

مصادر

  • Cormen, Leiserson, Rivest, Stein — "Introduction to Algorithms" (4th edition, MIT Press)، الفصل 3: Asymptotic Notation.
  • MDN Web Docs — توثيق Set وMap وخصائص الأداء الخاصة بيهم.
  • Node.js Performance Hooks documentation — perf_hooks module على nodejs.org.
  • Big-O Cheat Sheet — bigocheatsheet.com لتقديرات عملية لتعقيد البنى والخوارزميات الشائعة.
  • ECMAScript 2025 Specification — مواصفات تعقيد عمليات Set.prototype.has وMap.prototype.get.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة