Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

အသုံးပြုသူအားလုံးသည် မိုဘိုင်းအပလီကေးရှင်းများတွင် လျင်မြန်စွာ စတင်အသုံးပြုနိုင်ပြီး တုံ့ပြန်မှုရှိသော UI ကို လက်ခံရယူပါ။ အပလီကေးရှင်းကို စတင်ရန် အချိန်အတော်ကြာပါက အသုံးပြုသူသည် ဝမ်းနည်းခြင်းနှင့် ဒေါသထွက်ခြင်းတို့ကို စတင်ခံစားရသည်။ အပလီကေးရှင်းကို မစတင်မီတွင်ပင် သုံးစွဲသူ၏အတွေ့အကြုံကို အလွယ်တကူ လုယူနိုင်သည် သို့မဟုတ် သုံးစွဲသူကို လုံးဝဆုံးရှုံးနိုင်သည်။

Dodo Pizza အက်ပ်သည် ပျမ်းမျှအားဖြင့် စတင်ရန် ၃ စက္ကန့်ကြာမြင့်ကြောင်းနှင့် အချို့သော “ကံကောင်းသူများ” အတွက် ၁၅ စက္ကန့်မှ ၂၀ စက္ကန့်ကြာကြောင်း ကျွန်ုပ်တို့ တွေ့ရှိခဲ့သည်။

ဖြတ်တောက်မှုအောက်တွင် ပျော်ရွှင်ဖွယ်အဆုံးသတ်ဖြင့် ဇာတ်လမ်းတစ်ပုဒ်ဖြစ်သည်- Realm ဒေတာဘေ့စ် ကြီးထွားမှု၊ မှတ်ဉာဏ်ယိုစိမ့်မှု၊ ကျွန်ုပ်တို့ အသိုက်အမြုံအရာဝတ္ထုများကို စုဆောင်းပုံ၊ ထို့နောက် မိမိကိုယ်ကို ဆွဲထုတ်ကာ အရာအားလုံးကို ပြင်ဆင်ခြင်းအကြောင်း။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ
ဆောင်းပါးရေးသားသူ- Maxim ကချင်ကင် — Dodo Pizza ရှိ Android developer ။

အပလီကေးရှင်း အိုင်ကွန်ကို နှိပ်ရာမှ ပထမလုပ်ဆောင်ချက်၏ onResume() သို့ သုံးစက္ကန့်သည် အဆုံးမရှိဖြစ်သည်။ အချို့သောအသုံးပြုသူများအတွက်၊ စတင်ချိန်သည် 15-20 စက္ကန့်သို့ရောက်ရှိခဲ့သည်။ ဒါက ဘယ်လိုဖြစ်နိုင်မလဲ။

စာဖတ်ဖို့ အချိန်မရှိသူများအတွက် အတိုချုံးလေးပါ။
ကျွန်ုပ်တို့၏ Realm ဒေတာဘေ့စ်သည် အဆုံးမရှိသော ကြီးထွားလာခဲ့သည်။ အချို့သော အရာဝတ္ထုများကို ဖျက်မပစ်ဘဲ အဆက်မပြတ် စုဆောင်းနေပါသည်။ အပလီကေးရှင်း စတင်ချိန်သည် တဖြည်းဖြည်း တိုးလာသည်။ ထို့နောက် ကျွန်ုပ်တို့က ၎င်းကို ပြင်ဆင်ပြီး စတင်ချိန်သည် ပစ်မှတ်သို့ရောက်ရှိခဲ့သည် - ၎င်းသည် 1 စက္ကန့်ထက်နည်းလာပြီး မတိုးတော့ပါ။ ဆောင်းပါးတွင် အခြေအနေများကို ခွဲခြမ်းစိတ်ဖြာခြင်းနှင့် ဖြေရှင်းချက်နှစ်ခု - အမြန်တစ်ခုနှင့် ပုံမှန်တစ်ခု ပါဝင်သည်။

ပြဿနာကို ရှာဖွေပြီး ခွဲခြမ်းစိတ်ဖြာပါ။

ယနေ့ခေတ်တွင် မည်သည့်မိုဘိုင်းအပလီကေးရှင်းမဆို လျင်မြန်စွာနှင့် တုံ့ပြန်မှုရှိရမည်ဖြစ်သည်။ ဒါပေမယ့် အဲဒါက မိုဘိုင်းအက်ပ်အကြောင်းပဲ မဟုတ်ပါဘူး။ ဝန်ဆောင်မှုတစ်ခုနှင့် ကုမ္ပဏီတစ်ခုနှင့် အပြန်အလှန်ဆက်သွယ်မှုဆိုင်ရာ သုံးစွဲသူအတွေ့အကြုံသည် ရှုပ်ထွေးသောအရာဖြစ်သည်။ ဥပမာအားဖြင့်၊ ကျွန်ုပ်တို့၏အခြေအနေတွင်၊ ပေးပို့မှုအမြန်နှုန်းသည် ပီဇာဝန်ဆောင်မှုအတွက် အဓိကညွှန်ပြချက်တစ်ခုဖြစ်သည်။ ပို့ဆောင်မှုမြန်ဆန်ပါက ပီဇာပူလာမည်ဖြစ်ပြီး ယခုစားချင်သော customer များ အကြာကြီးစောင့်စရာမလိုပါ။ အက်ပလီကေးရှင်းအတွက်၊ တစ်ဖန်၊ မြန်ဆန်သောဝန်ဆောင်မှု၏ခံစားချက်ကိုဖန်တီးရန်အရေးကြီးသည်၊ အဘယ်ကြောင့်ဆိုသော်အပလီကေးရှင်းသည်စတင်ရန်စက္ကန့် 20 သာကြာပါက၊ ပီဇာကိုမည်မျှကြာအောင်စောင့်ဆိုင်းရမည်နည်း။

အစပိုင်းတွင်၊ ကျွန်ုပ်တို့ကိုယ်တိုင်သည် တစ်ခါတစ်ရံ လျှောက်လွှာကို စတင်ရန် စက္ကန့်အနည်းငယ်ကြာပြီးနောက် ၎င်းသည် အချိန်မည်မျှကြာသည်နှင့် ပတ်သက်၍ အခြားလုပ်ဖော်ကိုင်ဖက်များထံမှ တိုင်ကြားချက်များကို ကြားလာရတော့သည်။ ဒါပေမယ့် ဒီအခြေအနေကို ဆက်တိုက်ပြန်လုပ်လို့မရပါဘူး။

ဘယ်လောက်ကြာမှာလဲ? အရ Google စာရွက်စာတမ်းအက်ပလီကေးရှင်းတစ်ခု၏အေးစက်မှုသည် 5 စက္ကန့်ထက်နည်းပါက၊ ၎င်းကို "ပုံမှန်အတိုင်း" ဟုသတ်မှတ်သည်။ Dodo Pizza Android အက်ပ် (Firebase တိုင်းထွာချက်များအရ _app_start) မှာ အအေးစတင် ပျမ်းမျှအားဖြင့် ၃ စက္ကန့်အတွင်း - “မဆိုးဘူး၊ မကြောက်ဘူး” လို့ သူတို့ပြောကြတယ်။

သို့သော် နောက်ပိုင်းတွင် အက်ပလီကေးရှင်းကို စတင်ရန် အလွန်ကြာရှည်စွာ အချိန်ယူခဲ့ရကြောင်း တိုင်ကြားမှုများ စတင်ပေါ်ပေါက်လာသည်။ အစပြု၍ “အလွန်၊ အလွန်ရှည်” ဟူသည်ကို တိုင်းတာရန် ဆုံးဖြတ်ခဲ့သည်။ ပြီးတော့ အဲဒါအတွက် Firebase ခြေရာခံကို သုံးတယ်။ အက်ပ်ကို စတင်ခြေရာခံပါ။.

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

ဤစံနှုန်းခြေရာကောက်သည် အသုံးပြုသူအပလီကေးရှင်းကိုဖွင့်သည့်အချိန်နှင့် ပထမဆုံးလုပ်ဆောင်ချက်၏ onResume() ကို လုပ်ဆောင်သည့်အခိုက်အတန့်ကြားအချိန်ကို တိုင်းတာသည်။ Firebase Console တွင် ဤမက်ထရစ်ကို _app_start ဟုခေါ်သည်။ ထွက်ပေါ်လာခဲ့သည်-

  • 95th ရာခိုင်နှုန်းအထက် အသုံးပြုသူများအတွက် စတင်ဖွင့်ချိန်သည် 20 စက္ကန့်နီးပါး (အချို့ထက်ပိုကြာသည်) သည် ပျမ်းမျှအအေးစတင်ချိန်သည် 5 စက္ကန့်ထက်နည်းသော်လည်း၊
  • စတင်ချိန်သည် ကိန်းသေတန်ဖိုးမဟုတ်သော်လည်း အချိန်နှင့်အမျှ ကြီးထွားလာသည်။ ဒါပေမယ့် တစ်ခါတလေမှာ အစက်ချတာတွေရှိတယ်။ ခွဲခြမ်းစိတ်ဖြာမှုစကေးကို ရက် 90 အထိ တိုးမြှင့်လိုက်သောအခါ ဤပုံစံကို တွေ့ရှိခဲ့သည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

အတွေးနှစ်ခု ပေါ်လာသည် ။

  1. တစ်ခုခု ပေါက်ကြားနေတယ်။
  2. ဤ "တစ်စုံတစ်ခု" ကို ထုတ်ဝေပြီးနောက် ပြန်လည်သတ်မှတ်ပြီး ထပ်မံပေါက်ကြားသည်။

“ဒေတာဘေ့စ်နဲ့ တစ်ခုခုဖြစ်နိုင်တယ်၊” ဟု ကျွန်ုပ်တို့တွေးပြီး ကျွန်ုပ်တို့ မှန်ပါသည်။ ပထမဦးစွာ၊ ကျွန်ုပ်တို့သည် ဒေတာဘေ့စ်ကို ကက်ရှ်တစ်ခုအဖြစ် အသုံးပြုသည်၊ ရွှေ့ပြောင်းခြင်းအတောအတွင်း ၎င်းကို ကျွန်ုပ်တို့ ရှင်းလင်းခဲ့သည်။ ဒုတိယအနေနှင့်၊ အပလီကေးရှင်းစတင်သောအခါတွင်ဒေတာဘေ့စ်ကိုဖွင့်သည်။ အားလုံး လိုက်ဖက်ပါတယ်။

Realm ဒေတာဘေ့စ်မှာ ဘာဖြစ်နေတာလဲ

ကျွန်ုပ်တို့သည် ပထမဆုံးထည့်သွင်းခြင်းမှ စတင်ပြီး အသုံးပြုနေစဉ်အတွင်း ဒေတာဘေ့စ်၏ အကြောင်းအရာများသည် အပလီကေးရှင်း၏သက်တမ်းတစ်လျှောက် မည်သို့ပြောင်းလဲသွားသည်ကို စတင်စစ်ဆေးခဲ့ပါသည်။ သင်သည် Realm ဒေတာဘေ့စ်မှတဆင့် အကြောင်းအရာများကို ကြည့်ရှုနိုင်ပါသည်။ Stetho ပါ သို့မဟုတ် ဖိုင်မှတစ်ဆင့် ပိုမိုအသေးစိတ်ရှင်းလင်းစွာ ဖွင့်ပါ။ Realm Studio. ADB မှတစ်ဆင့် ဒေတာဘေ့စ်၏ အကြောင်းအရာများကို ကြည့်ရှုရန် Realm ဒေတာဘေ့စ်ဖိုင်ကို ကူးယူပါ-

adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}

မတူညီသောအချိန်များတွင် ဒေတာဘေ့စ်၏အကြောင်းအရာများကို ကြည့်ရှုပြီးနောက်၊ အချို့သောအမျိုးအစားတစ်ခု၏ အရာဝတ္ထုအရေအတွက်သည် အဆက်မပြတ်တိုးလာသည်ကို တွေ့ရှိရပါသည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ
ပုံတွင် ဖိုင်နှစ်ခုအတွက် Realm Studio ၏အပိုင်းအစကို ပြသသည်- ဘယ်ဘက်တွင် - တပ်ဆင်ပြီးနောက် အချိန်အတန်ကြာသော အပလီကေးရှင်းအခြေခံ၊ ညာဘက်တွင် - အသုံးပြုပြီးနောက်တွင်၊ အရာဝတ္ထု အရေအတွက်ကို သိမြင်နိုင်သည်။ ImageEntity и MoneyType သိသာထင်ရှားစွာ ကြီးထွားလာပါပြီ (စခရင်ရှော့တွင် အမျိုးအစားတစ်ခုစီ၏ အရာဝတ္ထုအရေအတွက်ကို ပြသသည်)။

ဒေတာဘေ့စ်တိုးတက်မှုနှင့် စတင်ချိန်အကြား ဆက်စပ်မှု

ထိန်းချုပ်မရသော ဒေတာဘေ့စ်တိုးတက်မှုသည် အလွန်ဆိုးရွားသည်။ သို့သော် ၎င်းသည် အပလီကေးရှင်းစတင်ချိန်ကို မည်သို့အကျိုးသက်ရောက်သနည်း။ ၎င်းကို ActivityManager မှတဆင့်တိုင်းတာရန် အလွန်လွယ်ကူသည်။ Android 4.4 မှစ၍၊ logcat သည် မှတ်တမ်းကို ပြသထားသည့် စာကြောင်းနှင့် အချိန်ကို ပြသသည်။ ဤအချိန်သည် အပလီကေးရှင်းကို စတင်လုပ်ဆောင်သည့်အချိန်မှ စတင်လုပ်ဆောင်သည့် အချိန်ကာလနှင့် ညီမျှသည်။ ဤကာလအတွင်း အောက်ပါဖြစ်ရပ်များ ဖြစ်ပေါ်လာသည်-

  • လုပ်ငန်းစဉ်ကိုစတင်ပါ။
  • အရာဝတ္ထုများ၏အစပြုခြင်း။
  • လှုပ်ရှားမှုများကို ဖန်တီးခြင်းနှင့် အစပြုခြင်း။
  • အပြင်အဆင် ဖန်တီးခြင်း။
  • လျှောက်လွှာကို ပုံဖေါ်ခြင်း။

ငါတို့နဲ့လိုက်ဖက်တယ်။ -S နှင့် -W အလံများဖြင့် ADB ကို run ပါက၊ စတင်ချိန်နှင့် တိုးချဲ့ထားသော output ကို သင်ရရှိနိုင်သည်-

adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

အဲဒီကနေ ဖမ်းရင် grep -i WaitTime အချိန်၊ ဤမက်ထရစ်စုစည်းမှုကို အလိုအလျောက်လုပ်ဆောင်နိုင်ပြီး ရလဒ်များကို အမြင်အာရုံဖြင့် ကြည့်ရှုနိုင်သည်။ အောက်ဖော်ပြပါဂရပ်သည် အပလီကေးရှင်း၏အေးစက်မှုစတင်သည့်အရေအတွက်အပေါ် အပလီကေးရှင်းစတင်ချိန်၏ မှီခိုမှုကိုပြသသည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

တစ်ချိန်တည်းမှာပင်၊ 4 MB မှ 15 MB မှ ကြီးထွားလာသည့် ဒေတာဘေ့စ်၏ အရွယ်အစားနှင့် ကြီးထွားမှုကြား ဆက်နွယ်မှု၏ တူညီသော သဘောသဘာဝရှိသည်။ စုစုပေါင်း၊ အချိန်ကြာလာသည်နှင့်အမျှ (အအေးစတင်ခြင်းနှင့်အတူ) အက်ပလီကေးရှင်းဖွင့်ချိန်နှင့်ဒေတာဘေ့စ်၏အရွယ်အစားနှစ်ခုလုံးသည်တိုးပွားလာသည်ကိုတွေ့ရသည်။ ငါတို့လက်ထဲမှာ အယူအဆတစ်ခုရှိတယ်။ အခု ကျန်တာတွေအားလုံးက မှီခိုမှုကို အတည်ပြုဖို့ပဲ။ ထို့ကြောင့်၊ ကျွန်ုပ်တို့သည် “ပေါက်ကြားမှုများ” ကို ဖယ်ရှားရန် ဆုံးဖြတ်ပြီး ၎င်းသည် လွှင့်တင်မှုကို အရှိန်မြှင့်နိုင်မလား။

အဆုံးမဲ့ဒေတာဘေ့စ်တိုးတက်မှုအတွက် အကြောင်းရင်းများ

"ပေါက်ကြားမှုများ" ကိုဖယ်ရှားခြင်းမပြုမီ၊ ၎င်းတို့အဘယ်ကြောင့်ပထမနေရာတွင်ပေါ်လာသည်ကိုနားလည်သင့်သည်။ ဒါကိုလုပ်ဖို့၊ Realm က ဘာလဲဆိုတာ သတိရလိုက်ရအောင်။

Realm သည် ဆက်နွယ်မှုမရှိသော ဒေတာဘေ့စ်တစ်ခုဖြစ်သည်။ ၎င်းသည် သင့်အား Android ရှိ ORM ဆက်စပ်ဒေတာဘေ့စ်မည်မျှဖော်ပြသည်နှင့် အလားတူနည်းဖြင့် အရာဝတ္ထုများကြားရှိ ဆက်ဆံရေးများကို ဖော်ပြခွင့်ပြုသည်။ တစ်ချိန်တည်းမှာပင် Realm သည် အရာဝတ္ထုများကို အသွင်ပြောင်းခြင်းနှင့် မြေပုံဆွဲခြင်း အနည်းဆုံးပမာဏဖြင့် မှတ်ဉာဏ်တွင် တိုက်ရိုက်သိမ်းဆည်းသည်။ ၎င်းသည် Realm ၏အစွမ်းသတ္တိဖြစ်ပြီး ၎င်းကို အဘယ်ကြောင့်နှစ်သက်သနည်းဟူသည့် disk မှဒေတာများကို အလွန်လျင်မြန်စွာဖတ်နိုင်စေပါသည်။

(ဤဆောင်းပါး၏ရည်ရွယ်ချက်အတွက်၊ ဤဖော်ပြချက်သည် ကျွန်ုပ်တို့အတွက် လုံလောက်ပါလိမ့်မည်။ Realm in the cool အကြောင်းကို သင်ပိုမိုဖတ်ရှုနိုင်ပါသည်။ စာရွက်စာတမ်း ဒါမှမဟုတ် သူတို့ထဲမှာ အကယ်ဒမီ).

များစွာသော developer များသည် ဆက်စပ်ဒေတာဘေ့စ်များ (ဥပမာ၊ ORM ဒေတာဘေ့စ်များကို ဘောင်အောက်ရှိ SQL) ဖြင့် ပိုမိုလုပ်ဆောင်လေ့ရှိသည်။ ပြီးတော့ cascading data တွေကို ဖျက်တာလိုမျိုး အရာတွေက ပေးတာနဲ့တူတယ်လို့ ထင်ရပါတယ်။ ဒါပေမယ့် Realm မှာမဟုတ်ပါဘူး။

စကားမစပ်၊ Cascade ဖျက်ခြင်းအင်္ဂါရပ်ကို အချိန်အတော်ကြာ တောင်းဆိုထားသည်။ ဒီ ပြန်လည်ပြင်ဆင်မှု и အခြား၎င်းနှင့်ဆက်စပ်၍ တက်ကြွစွာ ဆွေးနွေးခဲ့ပါသည်။ မကြာခင် ပြီးတော့မယ် ဆိုတဲ့ ခံစားချက်မျိုး ရှိတယ်။ ဒါပေမယ့်လည်း ဒီပြဿနာကို အလိုအလျောက်ဖြေရှင်းပေးမယ့် အားကောင်းပြီး အားနည်းတဲ့ လင့်ခ်တွေရဲ့ နိဒါန်းမှာ ဘာသာပြန်ဆိုထားတဲ့ အရာအားလုံးကို နိဒါန်းပါ။ ဒီလုပ်ငန်းမှာ အတော်လေး တက်ကြွပြီး တက်ကြွပါတယ်။ တောင်းဆိုချက်ဆွဲပြည်တွင်းအခက်အခဲကြောင့် ခေတ္တရပ်နားထားခြင်းဖြစ်သည်။

မဖျက်ဘဲ ဒေတာပေါက်ကြားခြင်း။

တည်ရှိခြင်းမရှိသော cascading ကို အားကိုးပါက ဒေတာပေါက်ကြားမှု မည်ကဲ့သို့ အတိအကျ ပေါက်ကြားနိုင်သနည်း။ Realm အရာဝတ္ထုများကို nested လုပ်ထားပါက ၎င်းတို့ကို ဖျက်ရပါမည်။
တကယ့် ဥပမာ (နီးပါး) ကို ကြည့်ရအောင်။ ကျွန်ုပ်တို့တွင် အရာဝတ္ထုတစ်ခုရှိသည်။ CartItemEntity:

@RealmClass
class CartItemEntity(
 @PrimaryKey
 override var id: String? = null,
 ...
 var name: String = "",
 var description: String = "",
 var image: ImageEntity? = null,
 var category: String = MENU_CATEGORY_UNKNOWN_ID,
 var customizationEntity: CustomizationEntity? = null,
 var cartComboProducts: RealmList<CartProductEntity> = RealmList(),
 ...
) : RealmObject()

တွန်းလှည်းရှိ ကုန်ပစ္စည်းတွင် ပုံတစ်ခုအပါအဝင် နယ်ပယ်အမျိုးမျိုးရှိသည်။ ImageEntityစိတ်ကြိုက်ပါဝင်ပစ္စည်းများ CustomizationEntity. ထို့အပြင်၊ စျေးဝယ်လှည်းရှိ ထုတ်ကုန်သည် ၎င်း၏ကိုယ်ပိုင်ထုတ်ကုန်အစုံဖြင့် ပေါင်းစပ်နိုင်သည်။ RealmList (CartProductEntity). စာရင်းသွင်းထားသော အကွက်များအားလုံးသည် Realm အရာဝတ္ထုများဖြစ်သည်။ အကယ်၍ ကျွန်ုပ်တို့သည် တူညီသော ID ဖြင့် အရာဝတ္ထုအသစ် (copyToRealm() / copyToRealmOrUpdate()) ကို ထည့်သွင်းပါက၊ ဤအရာဝတ္တုအား လုံးလုံးလျားလျား overwrite လုပ်ပါမည်။ သို့သော် အတွင်းပိုင်းအရာဝတ္တုအားလုံး (ရုပ်ပုံ၊ စိတ်ကြိုက်ပြင်ဆင်ခြင်းEntity နှင့် cartComboProducts) သည် မိဘနှင့် ချိတ်ဆက်မှုပြတ်တောက်ပြီး ဒေတာဘေ့စ်တွင် ကျန်ရှိနေမည်ဖြစ်သည်။

၎င်းတို့နှင့် ချိတ်ဆက်မှု ပြတ်တောက်သွားသောကြောင့် ၎င်းတို့ကို ကျွန်ုပ်တို့ မဖတ်တော့ဘဲ သို့မဟုတ် ဖျက်ပစ်တော့မည် မဟုတ်ပါ (ကျွန်ုပ်တို့သည် ၎င်းတို့ကို ပြတ်သားစွာ ဝင်ရောက်ကြည့်ရှုခြင်း သို့မဟုတ် “စားပွဲ” တစ်ခုလုံးကို မရှင်းလင်းပါက)။ ဒါကို "memory leaks" လို့ခေါ်တယ်။

Realm နှင့်အလုပ်လုပ်သောအခါ၊ ကျွန်ုပ်တို့သည် အစိတ်အပိုင်းအားလုံးကို ရှင်းရှင်းလင်းလင်းဖြတ်ကျော်ပြီး ထိုကဲ့သို့သောလုပ်ဆောင်မှုများမတိုင်မီ အရာအားလုံးကို ပြတ်သားစွာဖျက်ပစ်ရပါမည်။ ၎င်းကို ဥပမာအားဖြင့် ဤကဲ့သို့ လုပ်ဆောင်နိုင်သည်-

val entity = realm.where(CartItemEntity::class.java).equalTo("id", id).findFirst()
if (first != null) {
 deleteFromRealm(first.image)
 deleteFromRealm(first.customizationEntity)
 for(cartProductEntity in first.cartComboProducts) {
   deleteFromRealm(cartProductEntity)
 }
 first.deleteFromRealm()
}
// и потом уже сохраняем

ဒီလိုလုပ်ရင် အားလုံးက လုပ်သင့်လုပ်ထိုက်တာအတိုင်းပါပဲ။ ဤဥပမာတွင်၊ ပုံ၊ စိတ်ကြိုက်ပြင်ဆင်ခြင်းEntity နှင့် cartComboProducts အတွင်းရှိ အခြား nested ကွင်းများမရှိဟု ကျွန်ုပ်တို့ယူဆသည်၊ ထို့ကြောင့် အခြား nested loops များနှင့် deletes များမရှိပါ။

"အမြန်" ဖြေရှင်းချက်

ကျွန်ုပ်တို့ ပထမဆုံးလုပ်ရန် ဆုံးဖြတ်လိုက်သည်မှာ အလျင်မြန်ဆုံး ကြီးထွားနေသော အရာဝတ္ထုများကို ရှင်းထုတ်ပြီး ၎င်းသည် ကျွန်ုပ်တို့၏ မူလပြဿနာကို ဖြေရှင်းနိုင်မလား။ ပထမဦးစွာ၊ အရိုးရှင်းဆုံးနှင့် အလိုလိုသိသာဆုံး အဖြေကို ဖန်တီးခဲ့သည်၊ ဆိုလိုသည်မှာ- အရာဝတ္ထုတစ်ခုစီသည် ၎င်း၏ကလေးများကို ဖယ်ရှားရန်အတွက် တာဝန်ရှိသင့်သည်။ ၎င်းကိုလုပ်ဆောင်ရန်၊ ကျွန်ုပ်တို့သည် ၎င်း၏ nested Realm အရာဝတ္ထုများစာရင်းကို ပြန်ပေးသည့် အင်တာဖေ့စ်ကို မိတ်ဆက်ပေးခဲ့သည်-

interface NestedEntityAware {
 fun getNestedEntities(): Collection<RealmObject?>
}

ကျွန်ုပ်တို့သည် ၎င်းကို ကျွန်ုပ်တို့၏ Realm အရာဝတ္ထုများတွင် အကောင်အထည်ဖော်ခဲ့သည်-

@RealmClass
class DataPizzeriaEntity(
 @PrimaryKey
 var id: String? = null,
 var name: String? = null,
 var coordinates: CoordinatesEntity? = null,
 var deliverySchedule: ScheduleEntity? = null,
 var restaurantSchedule: ScheduleEntity? = null,
 ...
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       coordinates,
       deliverySchedule,
       restaurantSchedule
   )
 }
}

В getNestedEntities ကျွန်ုပ်တို့သည် ကလေးအားလုံးကို ပြားပြားစာရင်းအဖြစ် ပြန်ပေးသည်။ ထို့အပြင် ကလေးအရာဝတ္တုတစ်ခုစီသည် NestedEntityAware အင်တာဖေ့စ်ကို အကောင်အထည်ဖော်နိုင်သည်၊ ဥပမာအားဖြင့်၊ ၎င်းတွင် ဖျက်ရန်အတွင်းပိုင်း Realm အရာဝတ္တုများပါရှိသည်၊ ScheduleEntity:

@RealmClass
class ScheduleEntity(
 var monday: DayOfWeekEntity? = null,
 var tuesday: DayOfWeekEntity? = null,
 var wednesday: DayOfWeekEntity? = null,
 var thursday: DayOfWeekEntity? = null,
 var friday: DayOfWeekEntity? = null,
 var saturday: DayOfWeekEntity? = null,
 var sunday: DayOfWeekEntity? = null
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       monday, tuesday, wednesday, thursday, friday, saturday, sunday
   )
 }
}

စသည်တို့တွင်၊ အရာဝတ္ထုများ၏ အသိုက်များကို ထပ်ခါတလဲလဲ ပြုလုပ်နိုင်သည်။

ထို့နောက် ကျွန်ုပ်တို့သည် nested objects အားလုံးကို ထပ်ခါတလဲလဲ ဖျက်ပစ်သည့် နည်းလမ်းကို ရေးသည်။ နည်းလမ်း (တိုးချဲ့မှုအဖြစ် ပြုလုပ်ထားသည်) deleteAllNestedEntities ထိပ်တန်းအဆင့် အရာဝတ္ထုများနှင့် နည်းလမ်းအားလုံးကို ရရှိသည်။ deleteNestedRecursively NestedEntityAware အင်တာဖေ့စ်ကို အသုံးပြု၍ မြှုပ်ထားသည့်အရာအားလုံးကို ထပ်ခါတလဲလဲ ဖယ်ရှားသည်-

fun <T> Realm.deleteAllNestedEntities(entities: Collection<T>,
 entityClass: Class<out RealmObject>,
 idMapper: (T) -> String,
 idFieldName : String = "id"
 ) {

 val existedObjects = where(entityClass)
     .`in`(idFieldName, entities.map(idMapper).toTypedArray())
     .findAll()

 deleteNestedRecursively(existedObjects)
}

private fun Realm.deleteNestedRecursively(entities: Collection<RealmObject?>) {
 for(entity in entities) {
   entity?.let { realmObject ->
     if (realmObject is NestedEntityAware) {
       deleteNestedRecursively((realmObject as NestedEntityAware).getNestedEntities())
     }
     realmObject.deleteFromRealm()
   }
 }
}

ကျွန်ုပ်တို့ ဤအရာကို အလျင်မြန်ဆုံး ကြီးထွားနေသော အရာဝတ္ထုများဖြင့် ပြုလုပ်ခဲ့ပြီး ဖြစ်ပျက်ခဲ့သည်များကို စစ်ဆေးခဲ့သည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

ရလဒ်အနေဖြင့်၊ ဤဖြေရှင်းချက်ဖြင့် ကျွန်ုပ်တို့ ဖုံးအုပ်ထားသော အရာဝတ္ထုများသည် ကြီးထွားမှုရပ်တန့်သွားသည်။ အခြေခံ၏ အလုံးစုံ ကြီးထွားမှု နှေးကွေးသော်လည်း မရပ်တန့်ခဲ့ပါ။

"သာမန်" အဖြေ

အခြေသည် တဖြည်းဖြည်း ကြီးထွားလာသော်လည်း၊ ကြီးထွားနေဆဲဖြစ်သည်။ ဒီတော့ ငါတို့က ပိုကြည့်လာတယ်။ ကျွန်ုပ်တို့၏ပရောဂျက်သည် Realm တွင် ဒေတာသိမ်းဆည်းခြင်းကို အလွန်တက်ကြွစွာ အသုံးပြုစေသည်။ ထို့ကြောင့်၊ အရာဝတ္တုတစ်ခုစီအတွက် nested objects အားလုံးကိုရေးခြင်းသည် ပင်ပန်းမှုများပြားပြီး ကုဒ်ပြောင်းသည့်အခါ အရာဝတ္တုများကို သတ်မှတ်ရန်မေ့သွားသောကြောင့် အမှားအယွင်းများဖြစ်နိုင်ချေ တိုးလာပါသည်။

အင်တာဖေ့စ်တွေကို မသုံးဘူးဆိုတာ သေချာစေချင်ပေမယ့် အရာအားလုံးက သူ့ဘာသာသူ အလုပ်လုပ်ပါတယ်။

တစ်ခုခုကို သူ့ဘာသာသူ လုပ်ချင်တဲ့အခါ၊ ရောင်ပြန်ဟပ်မှုကို သုံးရမယ်။ ဒါကိုလုပ်ဖို့၊ class field တစ်ခုစီကိုဖြတ်ပြီး အဲဒါဟာ Realm object ဒါမှမဟုတ် objects စာရင်းဟုတ်မဟုတ် စစ်ဆေးနိုင်ပါတယ်။

RealmModel::class.java.isAssignableFrom(field.type)

RealmList::class.java.isAssignableFrom(field.type)

အကယ်၍ အကွက်သည် RealmModel သို့မဟုတ် RealmList ဖြစ်ပါက၊ ထို့နောက် ဤအကွက်၏အရာဝတ္တုကို nested အရာဝတ္ထုများစာရင်းသို့ ထည့်ပါ။ အရာအားလုံးသည် အထက်တွင်ပြုလုပ်ခဲ့သည့်အတိုင်း အတူတူပင်ဖြစ်သည်၊ ဤနေရာတွင် သူ့ဘာသာသူ လုပ်ဆောင်သွားမည်ဖြစ်သည်။ Cascade ဖျက်ခြင်းနည်းလမ်း ကိုယ်တိုင်က အလွန်ရိုးရှင်းပြီး ဤကဲ့သို့ ဖြစ်ပုံရသည်။

fun <T : Any> Realm.cascadeDelete(entities: Collection<T?>) {
 if(entities.isEmpty()) {
   return
 }

 entities.filterNotNull().let { notNullEntities ->
   notNullEntities
       .filterRealmObject()
       .flatMap { realmObject -> getNestedRealmObjects(realmObject) }
       .also { realmObjects -> cascadeDelete(realmObjects) }

   notNullEntities
       .forEach { entity ->
         if((entity is RealmObject) && entity.isValid) {
           entity.deleteFromRealm()
         }
       }
 }
}

တိုးချဲ့မှု filterRealmObject စစ်ထုတ်ပြီး Realm အရာဝတ္ထုများကိုသာ ဖြတ်သန်းပါ။ နည်းလမ်း getNestedRealmObjects ရောင်ပြန်ဟပ်မှုအားဖြင့်၊ ၎င်းသည် အစုအဝေးရှိ Realm အရာဝတ္ထုအားလုံးကို ရှာဖွေပြီး ၎င်းတို့ကို မျဉ်းသားသည့်စာရင်းတွင် ထည့်သွင်းထားသည်။ ထို့နောက် ကျွန်ုပ်တို့သည် အလားတူအရာကို ထပ်ခါတလဲလဲလုပ်သည်။ ဖျက်သည့်အခါ၊ သင်သည် အရာဝတ္တု၏ တရားဝင်မှု ရှိမရှိ စစ်ဆေးရန် လိုအပ်သည်။ isValidအဘယ်ကြောင့်ဆိုသော် မတူညီသော ပင်မအရာဝတ္တုများသည် တူညီသော အသိုက်အမြုံများ ရှိနေနိုင်သောကြောင့် ဖြစ်နိုင်သည်။ ၎င်းကိုရှောင်ရှားရန်နှင့် အရာဝတ္တုအသစ်များဖန်တီးသောအခါတွင် အိုင်ဒီ၏ အလိုအလျောက်မျိုးဆက်ကို ရိုးရိုးရှင်းရှင်းအသုံးပြုခြင်းက ပိုကောင်းပါတယ်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

getNestedRealmObjects နည်းလမ်းကို အပြည့်အဝ အကောင်အထည်ဖော်ခြင်း။

private fun getNestedRealmObjects(realmObject: RealmObject) : List<RealmObject> {
 val nestedObjects = mutableListOf<RealmObject>()
 val fields = realmObject.javaClass.superclass.declaredFields

// Проверяем каждое поле, не является ли оно RealmModel или списком RealmList
 fields.forEach { field ->
   when {
     RealmModel::class.java.isAssignableFrom(field.type) -> {
       try {
         val child = getChildObjectByField(realmObject, field)
         child?.let {
           if (isInstanceOfRealmObject(it)) {
             nestedObjects.add(child as RealmObject)
           }
         }
       } catch (e: Exception) { ... }
     }

     RealmList::class.java.isAssignableFrom(field.type) -> {
       try {
         val childList = getChildObjectByField(realmObject, field)
         childList?.let { list ->
           (list as RealmList<*>).forEach {
             if (isInstanceOfRealmObject(it)) {
               nestedObjects.add(it as RealmObject)
             }
           }
         }
       } catch (e: Exception) { ... }
     }
   }
 }

 return nestedObjects
}

private fun getChildObjectByField(realmObject: RealmObject, field: Field): Any? {
 val methodName = "get${field.name.capitalize()}"
 val method = realmObject.javaClass.getMethod(methodName)
 return method.invoke(realmObject)
}

ရလဒ်အနေဖြင့်၊ ကျွန်ုပ်တို့၏ client ကုဒ်တွင် ဒေတာမွမ်းမံမှုလုပ်ဆောင်မှုတစ်ခုစီအတွက် “cascading delete” ကို အသုံးပြုပါသည်။ ဥပမာအားဖြင့်၊ ထည့်သွင်းလုပ်ဆောင်မှုတစ်ခုအတွက် ၎င်းသည် ဤကဲ့သို့ဖြစ်နေသည်-

override fun <T : Entity> insert(
 entityInformation: EntityInformation,
 entities: Collection<T>): Collection<T> = entities.apply {
 realmInstance.cascadeDelete(getManagedEntities(entityInformation, this))
 realmInstance.copyFromRealm(
     realmInstance
         .copyToRealmOrUpdate(this.map { entity -> entity as RealmModel }
 ))
}

နည်းလမ်းက ပထမ getManagedEntities ပေါင်းထည့်ထားသော အရာဝတ္ထုအားလုံးကို လက်ခံရရှိပြီးနောက် နည်းလမ်းကို လက်ခံသည်။ cascadeDelete အသစ်မရေးမီ စုဆောင်းထားသော အရာအားလုံးကို ထပ်ခါတလဲလဲ ဖျက်ပါ။ အပလီကေးရှင်းတစ်လျှောက်လုံးတွင် ကျွန်ုပ်တို့သည် ဤချဉ်းကပ်မှုကို အသုံးပြုသည်။ Realm တွင် Memory ယိုစိမ့်မှု လုံးဝမရှိတော့ပါ။ အပလီကေးရှင်း၏ အေးစက်မှုစတင်သည့်အရေအတွက်အပေါ် စတင်ချိန်၏ မှီခိုမှုကို တူညီသော တိုင်းတာမှုပြုလုပ်ခြင်းဖြင့် ရလဒ်ကို ကျွန်ုပ်တို့ မြင်တွေ့ရသည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

အစိမ်းရောင်မျဉ်းသည် nested အရာဝတ္ထုများကို အလိုအလျောက် ကက်ကိတ်ဖျက်လိုက်ချိန်တွင် အအေးစတင်မှုအရေအတွက်အပေါ် အပလီကေးရှင်းစတင်ချိန်၏ မှီခိုမှုကို ပြသသည်။

ရလဒ်များနှင့် ကောက်ချက်

အမြဲကြီးထွားနေသော Realm ဒေတာဘေ့စ်သည် အပလီကေးရှင်းကို စတင်ရန် အလွန်နှေးကွေးစေသည်။ ကျွန်ုပ်တို့သည် nested အရာဝတ္ထုများ၏ ကိုယ်ပိုင် "cascading delete" ဖြင့် အပ်ဒိတ်တစ်ခု ထုတ်ပြန်ခဲ့သည်။ ယခု ကျွန်ုပ်တို့သည် ကျွန်ုပ်တို့၏ဆုံးဖြတ်ချက်သည် _app_start မက်ထရစ်မှတစ်ဆင့် လျှောက်လွှာစတင်ချိန်ကို မည်သို့အကျိုးသက်ရောက်သည်ကို စောင့်ကြည့်ပြီး အကဲဖြတ်ပါသည်။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

ခွဲခြမ်းစိတ်ဖြာမှုအတွက်၊ ကျွန်ုပ်တို့သည် ရက်ပေါင်း 90 ကြာ အချိန်ယူ၍ ကြည့်ရှုနိုင်သည်- အပလီကေးရှင်းဖွင့်ချိန်၊ ပျမ်းမျှနှင့် သုံးစွဲသူများ၏ 95th ရာခိုင်နှုန်းတွင် ကျရောက်သည့်အရာတို့သည် လျော့နည်းလာပြီး မတိုးတော့ပေ။

Realm တွင် ကာစကိတ် ဖျက်ခြင်း သည် ကြာမြင့်စွာ လွှင့်တင်ခြင်းအပေါ် အောင်မြင်မှု ရရှိခဲ့ပုံ

ခုနှစ်ရက်ကြာဇယားကိုကြည့်လျှင် _app_start မက်ထရစ်သည် လုံးဝလုံလောက်ပုံရပြီး 1 စက္ကန့်ထက်နည်းပါသည်။

_app_start ၏ ပျမ်းမျှတန်ဖိုးသည် 5 စက္ကန့်ထက်ကျော်လွန်ပါက Firebase သည် ပုံမှန်အားဖြင့် ၎င်းကို ထပ်ထည့်ရကျိုးနပ်ပါသည်။ သို့သော် ကျွန်ုပ်တို့မြင်နိုင်သည်အတိုင်း၊ သင်သည် ဤအရာကို အားမကိုးသင့်ဘဲ ဝင်ရောက်ပြီး အတိအလင်းစစ်ဆေးပါ။

Realm ဒေတာဘေ့စ်၏ထူးခြားချက်မှာ၎င်းသည်ဆက်စပ်မှုမရှိသောဒေတာဘေ့စ်ဖြစ်သည်။ အသုံးပြုရလွယ်ကူခြင်း၊ ORM ဖြေရှင်းချက်များနှင့် အရာဝတ္ထုချိတ်ဆက်ခြင်းများနှင့် ဆင်တူနေသော်လည်း၊ ၎င်းတွင် cascade ဖျက်ခြင်းမရှိပါ။

၎င်းကို ထည့်သွင်းစဉ်းစားခြင်းမရှိပါက၊ အသိုက်အမြုံအရာဝတ္ထုများ စုပြုံလာပြီး “ယိုစိမ့်ခြင်း” ဖြစ်လိမ့်မည်။ ဒေတာဘေ့စ်သည် အဆက်မပြတ်ကြီးထွားနေမည်ဖြစ်ပြီး ၎င်းသည် အပလီကေးရှင်း၏နှေးကွေးခြင်း သို့မဟုတ် စတင်ခြင်းအပေါ် သက်ရောက်မှုရှိမည်ဖြစ်သည်။

Realm ရှိ အရာဝတ္တုများကို လျင်မြန်စွာ ဖယ်ရှားနည်းကို ကျွန်ုပ်၏ အတွေ့အကြုံကို မျှဝေခဲ့သည်၊ ကွက်လပ်မဟုတ်သေးသော်လည်း အချိန်အတော်ကြာအောင် ပြောဆိုနေကြပါပြီ၊ သူတို့ပြော и သူတို့ပြော. ကျွန်ုပ်တို့၏ကိစ္စတွင်၊ ဤအရာသည် လျှောက်လွှာစတင်ချိန်ကို အလွန်အရှိန်မြှင့်စေသည်။

ဤအင်္ဂါရပ်၏ မကြာမီ ထွက်ပေါ်လာမည့် အသွင်အပြင်နှင့် ပတ်သက်၍ ဆွေးနွေးနေသော်လည်း Realm တွင် cascade ဖျက်ခြင်း မရှိခြင်းကို ဒီဇိုင်းဖြင့် လုပ်ဆောင်ပါသည်။ အကယ်၍ သင်သည် အပလီကေးရှင်းအသစ်တစ်ခုကို ဒီဇိုင်းဆွဲနေပါက ၎င်းကို ထည့်သွင်းစဉ်းစားပါ။ အကယ်၍ သင်သည် Realm ကိုအသုံးပြုနေပါက၊ သင့်တွင်ထိုကဲ့သို့သောပြဿနာများရှိမရှိစစ်ဆေးပါ။

source: www.habr.com