การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler
ค้นหาจุดที่ใช้ CPU สูงด้วย cProfile และการวิเคราะห์ทีละบรรทัด
การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องทำโปรไฟล์
การทำโปรไฟล์ช่วยระบุว่าฟังก์ชันใดใช้เวลามากที่สุด และช่วยชี้แนวทางการปรับปรุงประสิทธิภาพ ควรทำโปรไฟล์ก่อนปรับปรุงประสิทธิภาพเสมอ อย่าคาดเดา
import cProfile
def slow():
total = 0
for i in range(1_000_000):
total += i
return total
cProfile.run("slow()")การเรียกใช้ cProfile จาก CLI
ทำ Profile ของสคริปต์ทั้งไฟล์โดยไม่แก้ไขสคริปต์: python -m cProfile -s cumtime script.py จัดเรียงตาม cumtime, tottime หรือ calls
# python -m cProfile -s cumtime my_script.py
#
# ncalls tottime percall cumtime percall filename:lineno(function)
# 1000 0.500 0.001 2.100 0.002 utils.py:10(process)cProfile ในโค้ด
สร้าง cProfile.Profile เปิดใช้งานหรือปิดใช้งาน แล้วพิมพ์สถิติด้วย pstats
import cProfile, pstats, io
pr = cProfile.Profile()
pr.enable()
# ... code to profile ...
pr.disable()
stream = io.StringIO()
ps = pstats.Stats(pr, stream=stream).sort_stats("cumulative")
ps.print_stats(10) # top 10
print(stream.getvalue())การกรอง pstats
กรองผลลัพธ์ของเครื่องมือวิเคราะห์ประสิทธิภาพให้เหลือเฉพาะรูปแบบชื่อโมดูลหรือฟังก์ชันที่ระบุ โดยใช้ print_stats(pattern)
import cProfile, pstats
cProfile.run("my_function()", "profile.out")
stats = pstats.Stats("profile.out")
stats.sort_stats("tottime")
stats.print_stats("mymodule") # only mymodule functionsการวิเคราะห์ประสิทธิภาพระดับบรรทัด
line_profiler แสดงเวลาการทำงานของแต่ละบรรทัด ไม่ใช่แค่ของแต่ละฟังก์ชัน จึงจำเป็นสำหรับค้นหาบรรทัดที่ใช้เวลามากภายในฟังก์ชัน
# pip install line_profiler
# Decorate target function:
from line_profiler import profile
@profile
def process(data):
result = []
for item in data: # <- which line is slow?
result.append(item*2)
return result
# Run: kernprof -l -v script.pyCLI ของเครื่องมือวิเคราะห์ระดับบรรทัด
kernprof -l script.py เรียกใช้สคริปต์พร้อมเปิดการวิเคราะห์ระดับบรรทัด ส่วน -v จะแสดงรายงานทันที
# kernprof -l -v script.py
#
# Line # Hits Time Per Hit % Time Line Contents
# ======================================================
# 4 1 2.0 2.0 1.0 result = []
# 5 1000 120.0 0.1 60.0 for item in data:
# 6 1000 80.0 0.1 39.0 result.append(item*2)การวิเคราะห์ประสิทธิภาพใน Jupyter
Jupyter มีคำสั่งพิเศษ %prun (cProfile) และ %lprun (line_profiler)
# In a Jupyter cell:
# %prun -s cumulative my_function(data)
# %load_ext line_profiler
# %lprun -f my_function my_function(data)การระบุจุดที่ใช้เวลามาก
ให้มุ่งความสนใจไปที่ฟังก์ชันซึ่งมีเวลาแบบสะสมสูงที่สุด (รวมทั้งสายการเรียก) และเวลารวมสูงที่สุด (เฉพาะตัวฟังก์ชันเอง โดยไม่รวมฟังก์ชันที่ถูกเรียก)
# cumtime = total time including callees (find root cause)
# tottime = time in function itself (find where work happens)
#
# Optimise the function with highest tottime firstหลีกเลี่ยงการปรับปรุงประสิทธิภาพก่อนเวลาอันควร
ทำ Profile ก่อน แล้วจึงปรับปรุงจุดคอขวดที่วัดได้ วิธีเพิ่มความเร็วของ Python ที่พบบ่อย ได้แก่ ใช้ฟังก์ชันในตัว ย้ายลูปไปใช้ NumPy แคชการค้นหาที่ทำซ้ำ หรือเรียกใช้ C ผ่าน ctypes/cffi
# Before optimising:
# profile shows: process_row() 95% of time
# Speedup: vectorise with NumPy
import numpy as np
arr = np.array(data)
result = arr * 2 # 100x faster than Python looppy-spy: เครื่องมือวิเคราะห์แบบสุ่มตัวอย่าง
py-spy ทำ Profile ของโพรเซสที่กำลังทำงานโดยไม่แก้ไขโค้ด โดยเชื่อมต่อกับ PID ที่กำลังทำงานอยู่
# pip install py-spy
# Profile for 30 s and show flamegraph:
# py-spy top --pid 12345
# py-spy record -o profile.svg --pid 12345 --duration 30การวัดประสิทธิภาพด้วย timeit
ใช้ timeit สำหรับการวัดประสิทธิภาพขนาดเล็กของนิพจน์ที่เจาะจง
import timeit
result = timeit.timeit(
"[x*2 for x in range(1000)]",
number=10_000
)
print(f"{result:.3f} s for 10k runs")ตรวจสอบอย่างรวดเร็ว
tottime แสดงอะไรในรายงาน cProfile
สรุปทบทวน
ใช้ cProfile เพื่อค้นหาฟังก์ชันที่ทำงานช้า และใช้ line_profiler เพื่อค้นหาบรรทัดที่ทำงานช้า ทำ Profile ด้วย -s cumtime เพื่อค้นหาสาเหตุหลัก ปรับปรุงเฉพาะจุดที่พิสูจน์แล้วว่าเป็นจุดที่ใช้เวลามาก โดยใช้การประมวลผลแบบเวกเตอร์ของ NumPy การแคช หรือส่วนขยายภาษา C เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด
คำถามที่พบบ่อย
บทเรียน “การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler”
ค้นหาจุดที่ใช้ CPU สูงด้วย cProfile และการวิเคราะห์ทีละบรรทัด คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม
ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การนับจำนวนการอ้างอิงของ CPython
- ตัวเก็บขยะและการอ้างอิงแบบวนรอบ
- การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler
- การวิเคราะห์การใช้หน่วยความจำด้วย tracemalloc