On this page
Profiling — วัดว่าช้าตรงไหน
หาจุดที่ทำให้โปรแกรมช้าด้วยข้อมูลจริงจาก timeit และ cProfile แทนการเดา
เมื่อโปรแกรมช้า สัญชาตญาณมักเดาผิดว่าช้าตรงไหน การ profiling คือ "วัดของจริง" ว่าเวลาหมดไปกับส่วนไหน เพื่อจะได้แก้ถูกจุด — กฎข้อแรกของการ optimize คือ วัดก่อน อย่าเดา
timeit — วัดโค้ดเล็ก ๆ
ใช้เทียบว่า 2 วิธีเขียน วิธีไหนเร็วกว่า timeit รันโค้ดซ้ำหลายครั้งแล้วเฉลี่ย ให้ผลแม่นกว่าจับเวลาเอง
import timeit
# เทียบ: สร้าง list ด้วย loop vs comprehension
loop_time = timeit.timeit(
"result = []\nfor i in range(1000): result.append(i*i)",
number=10000,
)
comp_time = timeit.timeit(
"result = [i*i for i in range(1000)]",
number=10000,
)
print(f"loop: {loop_time:.3f}s")
print(f"comprehension: {comp_time:.3f}s") # มักเร็วกว่าtime.perf_counter — จับเวลาช่วงโค้ดจริง
import time
start = time.perf_counter()
total = sum(i * i for i in range(10_000_000))
elapsed = time.perf_counter() - start
print(f"ใช้เวลา {elapsed:.3f} วินาที")ใช้ time.perf_counter() สำหรับวัดช่วงเวลา (ความละเอียดสูง) ไม่ใช่ time.time() ที่ไว้ดูเวลานาฬิกาจริง — จำสำนวนนี้ได้จาก decorator @timer ในบท 1
cProfile — profile ทั้งโปรแกรม
เมื่อโปรแกรมใหญ่ ไม่รู้ว่าช้าตรงฟังก์ชันไหน cProfile วัดทุกฟังก์ชันให้ว่าถูกเรียกกี่ครั้งและใช้เวลาเท่าไร
import cProfile
def slow_function():
return sum(i ** 2 for i in range(1_000_000))
def main():
for _ in range(10):
slow_function()
cProfile.run("main()")# หรือรันทั้งไฟล์จาก command line
python -m cProfile -s cumtime myscript.pyผลลัพธ์มีคอลัมน์สำคัญ: ncalls (ถูกเรียกกี่ครั้ง), tottime (เวลาในฟังก์ชันเองไม่รวมลูก), cumtime (เวลารวมทั้งที่เรียกฟังก์ชันอื่น) — ดู cumtime สูง ๆ คือจุดที่ควรแก้ก่อน
"Premature optimization is the root of all evil" — อย่าเสียเวลาแต่งโค้ดให้เร็วในจุดที่ไม่ได้ช้าจริง เขียนให้ถูกและอ่านง่ายก่อน พอช้าค่อย profile หาจุดจริงแล้วแก้เฉพาะจุดนั้น (เชื่อมกับ Big-O ในบท DSA)
สรุปหัวข้อนี้
- timeit เทียบความเร็ว 2 วิธีเขียน (รันซ้ำเฉลี่ย)
- time.perf_counter() จับเวลาช่วงโค้ดจริง (ไม่ใช่ time.time)
- cProfile วัดทุกฟังก์ชัน — ดู cumtime สูงคือจุดแก้ก่อน
- วัดก่อนแก้เสมอ — อย่า optimize จุดที่ไม่ได้ช้าจริง
1) ใช้ timeit เทียบ "x in list" กับ "x in set" บนข้อมูล 10000 ตัว 2) ใช้ perf_counter จับเวลาฟังก์ชันที่เขียนเอง 3) ใช้ cProfile กับโปรแกรมที่มีหลายฟังก์ชัน หาว่า cumtime สูงสุดอยู่ที่ไหน 4) อธิบายความหมายของ premature optimization