On this page
Big-O Notation — วัดประสิทธิภาพ
บอกว่าเมื่อข้อมูลใหญ่ขึ้น อัลกอริทึมทำงานหนักขึ้นเร็วแค่ไหน — ภาษากลางในการพูดถึงความเร็ว
Big-O เป็นหัวข้อที่คนกลัว แต่จริง ๆ ไม่ยาก มันคือวิธีบอกว่า "เมื่อข้อมูลใหญ่ขึ้น จำนวนขั้นตอนเพิ่มขึ้นเร็วแค่ไหน" เราไม่นับวินาทีจริง (เพราะขึ้นกับเครื่อง) แต่นับว่างานโตตามขนาดข้อมูล n อย่างไร เป็นภาษากลางที่โปรแกรมเมอร์ทั่วโลกใช้คุยกัน
ตารางอันดับความเร็ว
| Big-O | ชื่อ | n=10 | n=1000 | ความเร็ว |
|---|---|---|---|---|
| O(1) | คงที่ | 1 | 1 | 🟢 เร็วสุด |
| O(log n) | ลอการิทึม | ~3 | ~10 | 🟢 เร็วมาก |
| O(n) | เชิงเส้น | 10 | 1,000 | 🟡 ดี |
| O(n log n) | — | ~33 | ~10,000 | 🟡 ยอมรับได้ |
| O(n²) | กำลังสอง | 100 | 1,000,000 | 🔴 ช้าเมื่อ n ใหญ่ |
| O(2ⁿ) | เอกซ์โพเนนเชียล | 1,024 | เยอะมหาศาล | 🔴 ช้ามาก |
สังเกตว่าเมื่อ n=1000 ความต่างระหว่าง O(n) (พันขั้น) กับ O(n²) (ล้านขั้น) มหาศาล นี่คือเหตุผลที่เราใส่ใจ Big-O
ดูตัวอย่างแต่ละระดับ
# O(1) — คงที่ ไม่ขึ้นกับขนาดลิสต์
def first(items):
return items[0] # ทำงานครั้งเดียวเสมอ
# O(n) — วนครั้งเดียว โตตามขนาด
def contains(items, target):
for x in items: # n รอบ
if x == target:
return True
return False
# O(n²) — loop ซ้อน loop
def has_duplicate(items):
for i in range(len(items)): # n รอบ
for j in range(i + 1, len(items)): # อีก n รอบ
if items[i] == items[j]:
return True
return Falseวิธีอ่าน Big-O ของโค้ด
- ไม่มี loop, แค่คำนวณ/เข้าถึง index/dict → O(1)
- loop เดียววนทั้งข้อมูล → O(n)
- loop ซ้อนสองชั้น (ทั้งคู่วนตามข้อมูล) → O(n²)
- แบ่งครึ่งข้อมูลทุกรอบ (เช่น binary search) → O(log n)
- เรียงลำดับ (sort) → O(n log n)
Big-O สนใจแค่แนวโน้มเมื่อ n ใหญ่มาก จึง (1) ตัดค่าคงที่ทิ้ง: O(2n) เขียนเป็น O(n) (2) เก็บแค่พจน์ที่โตเร็วสุด: O(n² + n) เขียนเป็น O(n²) เพราะ n² ครอบงำเมื่อ n ใหญ่
Space Complexity — หน่วยความจำก็นับ
Big-O ใช้วัดหน่วยความจำที่ใช้ด้วย ไม่ใช่แค่เวลา เช่นถ้าสร้างลิสต์ใหม่ขนาดเท่า input ก็ใช้ O(n) space ส่วนการใช้ตัวแปรไม่กี่ตัวคือ O(1) space
# O(1) space — ใช้ตัวแปรไม่กี่ตัว ไม่ว่า input ใหญ่แค่ไหน
def total(nums):
s = 0
for n in nums:
s += n
return s
# O(n) space — สร้างลิสต์ใหม่ขนาดเท่า input
def doubled(nums):
return [n * 2 for n in nums]สรุปหัวข้อนี้
- Big-O บอกว่างานโตตามขนาดข้อมูล n อย่างไร (ไม่ใช่วินาทีจริง)
- อันดับจากเร็วไปช้า: O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ)
- อ่านจากจำนวน loop ที่ซ้อนกัน: เดียว=O(n), สองชั้น=O(n²), แบ่งครึ่ง=O(log n)
- ตัดค่าคงที่และเก็บพจน์ที่โตเร็วสุด
- Space complexity วัดหน่วยความจำ: ตัวแปรไม่กี่ตัว=O(1), สร้างลิสต์ใหม่=O(n)
1) บอก Big-O ของฟังก์ชันที่มี for loop เดียว 2) บอก Big-O ของ loop ซ้อน 3 ชั้น 3) วิเคราะห์ว่า has_duplicate ข้างบนเป็น O อะไร และคิดวิธีทำให้เป็น O(n) ด้วย set 4) บอก space complexity ของฟังก์ชันที่ reverse ลิสต์โดยสร้างลิสต์ใหม่