آپ کا SQL تیز ہے لیکن API سست ہے
آپ کی ڈیٹا بیس کوئریز تیز ہیں۔ آپ کا کیشنگ (caching) کام کر رہا ہے۔ آپ کے بیک گراؤنڈ جابز ٹھیک ہیں۔
پھر بھی، آپ کی API اب بھی سست ہے۔ آپ کا CPU استعمال زیادہ ہے۔
مسئلہ آپ کا ڈیٹا بیس نہیں ہے۔ مسئلہ Ruby لیئر کا ہے۔
رکاوٹ (bottleneck) اکثر اس وقت آتی ہے جب ڈیٹا ڈیٹا بیس سے نکل کر آپ کی ایپلی کیشن میں داخل ہوتا ہے۔ یہ تین اہم مسائل کی وجہ سے ہوتا ہے:
- ضرورت سے زیادہ سیریلائزیشن (Bloated serialization)
- اشیاء کی ضرورت سے زیادہ تخصیص (Excessive object allocation)
- بار بار ہونے والی کیلکولیشن (Repeated computation)
یہ رہا انہیں ٹھیک کرنے کا طریقہ۔
- ضرورت سے زیادہ سیریلائزیشن (Bloated Serialization) کو روکیں
بہت سے ڈویلپرز پورے ماڈلز کو JSON میں تبدیل کر دیتے ہیں۔
render json: @shipments
اگر ایک شپمنٹ میں 40 کالم ہیں لیکن آپ کے فرنٹ اینڈ کو صرف 5 کی ضرورت ہے، تو آپ CPU سائیکلز ضائع کر رہے ہیں۔ آپ سے API keys یا لاگت (costs) جیسے نجی ڈیٹا کے لیک ہونے کا خطرہ بھی ہوتا ہے۔
حل: صرف وہی فیلڈز واپس کریں جن کی آپ کو ضرورت ہے۔
render json: @shipments.as_json(only: [:id, :tracking_no, :status])
مزید بہتر رفتار کے لیے، ڈیٹا کو ایرے (arrays) کے طور پر حاصل کرنے کے لیے pluck کا استعمال کریں۔ یہ مکمل طور پر بھاری ActiveRecord اشیاء بنانے سے بچاتا ہے۔
- آبجیکٹ الوکیشن (Object Allocation) کو کم کریں
Ruby جو بھی آبجیکٹ بناتا ہے وہ میموری لیتا ہے۔ ایک ہی ریکویسٹ کے دوران ہزاروں آبجیکٹس بنانا گاربیج کلیکٹر (Garbage Collector - GC) کو زیادہ محنت کرنے پر مجبور کرتا ہے۔ یہ آپ کے پورے سسٹم کو سست کر دیتا ہے۔
لوپس (loops) کے اندر نئے ہیش (hashes) یا اسٹرنگز (strings) بنانے سے گریز کریں۔
غلط:
@shipments.map do |s|
{ label: "#{s.tracking_no} - #{s.status.upcase}" }
end
درست: اسٹیٹک ڈیٹا کو لوپ سے باہر منتقل کریں۔ Ruby کے بجائے ڈیٹا بیس میں زیادہ کام کریں۔
- بار بار ہونے والی کیلکولیشن (Repeated Computation) سے بچیں
اگر آپ ایک ہی ریکویسٹ میں ایک ہی میتھڈ کو کئی بار کال کرتے ہیں، تو آپ وقت ضائع کرتے ہیں۔
مثال:
def total_weight
shipments.sum(&:weight)
end
اگر آپ کا ویو (view)، ہیلپر (helper)، اور سیریلائزر (serializer) سب اسے کال کرتے ہیں، تو آپ تین بار مجموعہ (sum) کیلکولیٹ کرتے ہیں۔
حل: میموائزیشن (memoization) کا استعمال کریں۔
def total_weight
@total_weight ||= shipments.sum(&:weight)
end
یہ اس بات کو یقینی بناتا ہے کہ حساب کتاب ایک ریکویسٹ میں صرف ایک بار ہو۔
خلاصہ ٹیبل:
- ضرورت سے زیادہ سیریلائزیشن (Bloated serialization): صرف مطلوبہ فیلڈز واپس کریں یا
pluckاستعمال کریں۔ - زیادہ الوکیشن (High allocation): لوپس میں کم آبجیکٹس بنائیں۔
- بار بار ہونے والی کیلکولیشن (Repeated computation): نتائج کو دوبارہ استعمال کرنے کے لیے میموائزیشن کا استعمال کریں۔
ڈیٹا بیس کی آپٹیمائزیشن (optimization) کا مطلب ہے کم ڈیٹا مانگنا۔ ایپلی کیشن کی آپٹیمائزیشن کا مطلب ہے کہ ڈیٹا حاصل کرنے کے بعد کم سے کم غیر ضروری کام کرنا۔
ماخذ: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno
