0Pricing
Python Academy · บทเรียน

การวิเคราะห์ประสิทธิภาพด้วย 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.py

CLI ของเครื่องมือวิเคราะห์ระดับบรรทัด

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 loop

py-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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การนับจำนวนการอ้างอิงของ CPython
  2. ตัวเก็บขยะและการอ้างอิงแบบวนรอบ
  3. การวิเคราะห์ประสิทธิภาพด้วย cProfile และ line_profiler
  4. การวิเคราะห์การใช้หน่วยความจำด้วย tracemalloc
← กลับไปที่ Python Academy