Thuta Learning
Data Structures & Algorithms
BasicProgrammingintermediate

Big-O Notation — Growth Rate ကို တိုင်းတာခြင်း

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Big-O Notation — Growth Rate ကို တိုင်းတာခြင်း concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ Python code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Big-O notation ဟာ algorithm တစ်ခုရဲ့ cost — time သို့မဟုတ် memory — ဟာ input size n ကြီးလာတာနှင့်အမျှ ဘယ်လိုကြီးထွားလာလဲဆိုတာကို ဖော်ပြတာဖြစ်ပြီး၊ laptop ပေါ်မှာ literal second ဘယ်လောက်ကြာလဲဆိုတာကို ဖော်ပြတာ မဟုတ်ပါဘူး။ ဒီကွာခြားချက်က အရေးကြီးတာက raw second ဟာ CPU speed, language, ဒီနေ့ system load ပေါ်မူတည်နေပြီး n နှစ်ဆတိုးလာရင် (သို့) ထောင်ဆတိုးလာရင် algorithm ဘယ်လိုပြုမူလဲဆိုတာ ဘာမှမပြောနိုင်ဘူး — growth rate ဟာ scale ဖြစ်တဲ့အခါ တကယ်ခန့်မှန်းပေးနိုင်တဲ့ property ဖြစ်ပါတယ်။ Big-O က constant factor တွေနှင့် lower-order term တွေကို တမင်ရည်ရွယ်ပြီး လျစ်လျူရှုပါတယ် — operation 3n+100 လုပ်တဲ့ algorithm တစ်ခုနှင့် n ပဲ လုပ်တဲ့ algorithm တစ်ခု နှစ်ခုစလုံးဟာ O(n) ဖြစ်ပါတယ်၊ ဘာလို့လဲဆိုတော့ n တစ်ခုအထက်ကျရင် constant multiplier က curve မြင့်တက်မှုနှုန်းနှင့်စာရင် အရေးမပါတော့လို့ပါ။ ရှုးခြားအောင်းရေး (best ကနေ worst) ordered common class တွေကတော့ O(1) constant, O(log n) logarithmic, O(n) linear, O(n log n) linearithmic, နှင့် O(n²) quadratic တို့ဖြစ်ပါတယ်။ function တစ်ခုရဲ့ complexity ကို ခန့်မှန်းဖို့ nested loop နှင့် lookup တွေကို ရေတွက်ပါ — n item တွေကို တစ်ကြိမ်ဖြတ်သွားတာက O(n); loop ထဲမှာ loop တစ်ခု n အတွက် ထည့်လိုက်ရင် O(n²); dictionary (သို့) set lookup တစ်ခုက item ဘယ်နှစ်ခုပါလဲမကြည့်ဘဲ O(1) ဖြစ်ပါတယ်။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Tutorial Platform ရဲ့ search feature က result တွေကို rank လုပ်တဲ့အခါ O(n log n) sort တစ်ခုနှင့် မတော်တဆ O(n²) ဖြစ်သွားတဲ့ sort (ဥပမာ naive bubble sort သို့မဟုတ် ထပ်ခါထပ်ခါ linear re-scan) ကြားက ကွာခြားချက်ဟာ lesson အနည်းငယ်ကို ချက်ချင်း rank လုပ်နိုင်တာနှင့် catalog က lesson ထောင်ချီရှိလာတဲ့အခါ page freeze ဖြစ်သွားတာ ကြားက ကွာခြားချက်ပါပဲ။ complexity class တွေကို သိထားခြင်းဟာ profiler တစ်ခု run မလုပ်ခင်ကတည်းက — slug-to-content အတွက် dict lookup တစ်ခုနှင့် lesson record တိုင်းကို linear scan လုပ်ခြင်း — ဘယ် implementation ရွေးချယ်မှုက content ဆက်တိုးလာသည့်တိုင် platform ကို responsive ဖြစ်နေအောင် ထိန်းသိမ်းပေးမလဲဆိုတာကို ကြိုတင်ခန့်မှန်းနိုင်စေပါတယ်။

အတူတူ စမ်းရေးကြည့်မယ်

python
def find_max_linear(numbers):
    # Single pass over all n items -> O(n): cost grows directly with input size
    current_max = numbers[0]
    for num in numbers:
        if num > current_max:
            current_max = num
    return current_max

def lookup_price(catalog, item_name):
    # dict lookup by key -> O(1): cost stays flat no matter how big catalog gets
    return catalog.get(item_name)

numbers = [4, 19, 2, 77, 5, 42]
catalog = {'pen': 500, 'book': 3500, 'bag': 12000}

print('Max (O(n) scan):', find_max_linear(numbers))
print('Price lookup (O(1)):', lookup_price(catalog, 'book'))
You should see
element တိုင်းကို တစ်ကြိမ် scan လုပ်ခြင်းမှ 'Max (O(n) scan): 77' နှင့် catalog size ဘယ်လောက်ပဲရှိရှိ dict lookup တစ်ကြိမ်တည်းမှ 'Price lookup (O(1)): 3500' ကို print ထုတ်ပေးသည်။

၅ မိနစ် စမ်းကြည့်

`numbers` ထဲမှာ target value တစ်ခုရှိမရှိ for-loop နဲ့ စစ်ဆေးတဲ့ function တစ်ခုနှင့် numbers အတူတူကို set အဖြစ်ပြောင်းပြီး membership စစ်ဆေးတဲ့ function တစ်ခု ထပ်ထည့်ပါ။ numbers ကို item 100,000 အထိ scale တိုးပြီး နှစ်ခုစလုံးကို timing နှိုင်းယှဉ်ကြည့်ပါ။

သတိလေးတစ်ချက်

implementation နှစ်ခုကို data item ငါးခုလို သေးငယ်တဲ့ input နှင့်ပဲ benchmark လုပ်ပြီး performance အတူတူပဲလို့ ကောက်ချက်ချခြင်း — O(n) နှင့် O(1) approach တွေဟာ n ကြီးမှသာ growth-rate ကွာခြားချက်က ပေါ်လာမှာဖြစ်ပါတယ်။

'ဒီ function မှာ code line ရေ နည်းတယ်' ဆိုတာနှင့် 'ဒီ function မြန်တယ်' ဆိုတာကို ရောထွေးမိခြင်း — line တစ်ကြောင်းတည်းနဲ့ ရေးထားပေမယ့် nested loop ဖုံးထားနိုင်ပြီး O(n²) ဖြစ်နေနိုင်တယ်၊ dict သုံးထားတဲ့ function ရှည်ရှည်ကြီးက O(n) ဖြစ်နိုင်ပါတယ်။

Wikipedia — Big O notationData Structures & Algorithms

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • implementation နှစ်ခုကို data item ငါးခုလို သေးငယ်တဲ့ input နှင့်ပဲ benchmark လုပ်ပြီး performance အတူတူပဲလို့ ကောက်ချက်ချခြင်း — O(n) နှင့် O(1) approach တွေဟာ n ကြီးမှသာ growth-rate ကွာခြားချက်က ပေါ်လာမှာဖြစ်ပါတယ်။
  • 'ဒီ function မှာ code line ရေ နည်းတယ်' ဆိုတာနှင့် 'ဒီ function မြန်တယ်' ဆိုတာကို ရောထွေးမိခြင်း — line တစ်ကြောင်းတည်းနဲ့ ရေးထားပေမယ့် nested loop ဖုံးထားနိုင်ပြီး O(n²) ဖြစ်နေနိုင်တယ်၊ dict သုံးထားတဲ့ function ရှည်ရှည်ကြီးက O(n) ဖြစ်နိုင်ပါတယ်။
  • နမူနာ code ကို production system ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test environment တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

`numbers` ထဲမှာ target value တစ်ခုရှိမရှိ for-loop နဲ့ စစ်ဆေးတဲ့ function တစ်ခုနှင့် numbers အတူတူကို set အဖြစ်ပြောင်းပြီး membership စစ်ဆေးတဲ့ function တစ်ခု ထပ်ထည့်ပါ။ numbers ကို item 100,000 အထိ scale တိုးပြီး နှစ်ခုစလုံးကို timing နှိုင်းယှဉ်ကြည့်ပါ။

You'll know it worked when: element တိုင်းကို တစ်ကြိမ် scan လုပ်ခြင်းမှ 'Max (O(n) scan): 77' နှင့် catalog size ဘယ်လောက်ပဲရှိရှိ dict lookup တစ်ကြိမ်တည်းမှ 'Price lookup (O(1)): 3500' ကို print ထုတ်ပေးသည်။

Big-O Notation — Growth Rate ကို တိုင်းတာခြင်း | Thuta Learning