0Pricing
Ruby Academy · درس

الاختناقات الشائعة

تسريع شيفرة Ruby

الاختناقات الشائعة درس مجاني في Ruby Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Ruby Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Ruby Academy 4 دروس في المجموع.

التعرّف إلى اختناقات الأداء

تنتج معظم حالات البطء في Ruby عن بضعة أنماط متكررة. ومعرفتها تتيح لكم إصلاح الكود بسرعة.

  • استخدام بنية بيانات غير مناسبة للمهمة
  • تكرار عمل كان من الممكن تخزينه مؤقتًا
  • استعلامات N+1 وحلقات متداخلة

يغطي هذا الدرس أكثر المشكلات شيوعًا.

puts 'Speeding up Ruby starts with knowing the usual suspects'

Array#include? مقابل Set

يستغرق التحقق من العضوية باستخدام Array#include? وقتًا من الرتبة O(n). يوفر Set أو الـ Hash عمليات بحث من الرتبة O(1).

  • عند تكرار عمليات التحقق من العضوية، أنشئوا Set مرة واحدة
  • تحسين كبير جدًا في السرعة مع المجموعات الكبيرة
require 'set'

allowed = Set.new(['a', 'b', 'c'])
puts allowed.include?('b')
puts allowed.include?('z')

الحلقات المتداخلة (O(n²))

تُعد مقارنة كل زوج من العناصر عملية تربيعية، ويتفاقم زمنها بشدة مع زيادة الحجم.

  • استبدلوا الحلقات الداخلية بعملية بحث في Hash
  • تحوّل التعقيد من O(n²) إلى O(n)
a = [1, 2, 3, 4]
b = [3, 4, 5]
set_b = b.to_set rescue require('set') || b.to_set
common = a.select { |x| set_b.include?(x) }
puts common.inspect

نمط N+1

يؤدي جلب البيانات المرتبطة داخل حلقة إلى N+1 عملية.

  • استعلام واحد للقائمة، ثم استعلام واحد لكل عنصر
  • جمّعوا عمليات البحث بدلًا من ذلك في جلب واحد مجمّع
# Bad: lookup inside loop
orders = [1, 2, 3]
prices = { 1 => 10, 2 => 20, 3 => 30 }
# Good: one preloaded hash, O(1) per item
total = orders.sum { |id| prices[id] }
puts total

الحفظ المؤقت للنتائج

تؤدي إعادة حساب القيمة المكلفة نفسها إلى إهدار الوقت. احفظوها مؤقتًا باستخدام ||=.

  • خزّنوا النتيجة مؤقتًا بعد حسابها للمرة الأولى
  • تعيد الاستدعاءات اللاحقة النتيجة فورًا
class Report
  def total
    @total ||= begin
      puts 'computing...'
      (1..1000).sum
    end
  end
end

r = Report.new
puts r.total
puts r.total

اختيار الأسلوب المناسب

تكون بعض أساليب Enumerable أسرع بكثير من السلاسل المتتابعة.

  • يتفوق sum على inject(:+)
  • يتوقف any? فورًا عند تحقق النتيجة، بخلاف select.empty?
  • يتوقف find عند أول تطابق
nums = (1..1_000_000)
puts nums.any? { |n| n > 5 }
puts nums.find { |n| n > 5 }

تجنّب الفرز المتكرر

يُعد الفرز داخل حلقة أو تكراره مكلفًا. أجروا الفرز مرة واحدة وأعيدوا استخدام النتيجة.

  • يستغرق الفرز O(n log n)
  • خزّنوا النتيجة المرتبة مؤقتًا إذا كانت البيانات مستقرة
data = [5, 2, 8, 1, 9]
sorted = data.sort
puts sorted.first
puts sorted.last

التجميع باستخدام Hash

يجمع group_by وtally البيانات في مرور واحد بدلًا من إجراء عمليات بحث متكررة.

  • يعدّ tally مرات الظهور بكفاءة
  • يتجنب حلقات العد اليدوية
words = ['a', 'b', 'a', 'c', 'b', 'a']
puts words.tally.inspect

تكلفة بناء السلاسل النصية

يكون الضم باستخدام join أسرع من الضم المتكرر عند التعامل مع المجموعات.

  • أنشئوا مصفوفة، ثم استخدموا join مرة واحدة
  • يتجنب إنشاء العديد من السلاسل النصية الوسيطة
parts = (1..5).map { |i| "item#{i}" }
puts parts.join(', ')

تجميع التعبيرات النمطية

يؤدي تعريف تعبير نمطي حرفي داخل حلقة كثيفة الاستخدام إلى إعادة تجميعه ضمنيًا. انقلوه إلى ثابت.

  • جمّعوه مرة واحدة وطابقوا به مرات عديدة
  • استخدموا match? عندما تحتاجون إلى قيمة منطقية فقط
EMAIL = /\A[^@\s]+@[^@\s]+\z/

inputs = ['a@b.com', 'nope', 'x@y.org']
valid = inputs.select { |s| EMAIL.match?(s) }
puts valid.inspect

تأجيل تنفيذ العمل

لا تحسبوا ما قد لا تستخدمونه أبدًا. أجّلوا التنفيذ باستخدام التقييم الكسول أو الشروط الواقية.

  • أعيدوا النتيجة مبكرًا متى أمكن
  • احسبوا القيم المكلفة عند الطلب فقط
def describe(items)
  return 'empty' if items.empty?
  "#{items.size} items, first is #{items.first}"
end

puts describe([])
puts describe([10, 20])

اختبار سريع

اختبروا معرفتكم باختناقات الأداء.

مراجعة

تعلّمتم كيفية إصلاح اختناقات الأداء الشائعة:

  • استخدموا Set أو Hash للتحقق السريع من العضوية بدلًا من include?
  • أزيلوا الحلقات المتداخلة وأنماط N+1 باستخدام Hash محمّلة مسبقًا
  • احفظوا الحسابات المكلفة مؤقتًا باستخدام ||=
  • اختاروا الأساليب الفعّالة مثل sum وany? وtally، وانقلوا التعبيرات النمطية إلى خارج الحلقات
  • أجّلوا العمل الذي قد لا تحتاجون إليه أو تخطّوه

احرصوا دائمًا على القياس قبل التحسين وبعده للتحقق من المكاسب.

الأسئلة الشائعة

هل درس «الاختناقات الشائعة» مجاني؟

نعم — نص درس «الاختناقات الشائعة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Ruby Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Ruby Academy 4 دروس في المجموع.

ماذا ستتعلم في «الاختناقات الشائعة»؟

تسريع شيفرة Ruby تتمرن على Ruby Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Ruby Academy؟

لا تُشترط خبرة سابقة. Ruby Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «الاختناقات الشائعة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Ruby Academy هذا؟

نعم. كل درس في Ruby Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. قياس الأداء
  2. أدوات تحليل الأداء
  3. تحسين الذاكرة
  4. الاختناقات الشائعة
← العودة إلى Ruby Academy