โครงการออยเลอร์และการแข่งขันการเข้ารหัสอื่น ๆ มักจะมีเวลาสูงสุดในการรัน กับงูหลามบางครั้งแนวทางที่ค่อนข้างค่อนข้างแออัดเกินไป - __main__คือการเพิ่มรหัสระยะเวลาที่จะ
วิธีที่ดีในการทำโพรไฟล์ว่าโปรแกรม Python ใช้เวลานานแค่ไหน?
โครงการออยเลอร์และการแข่งขันการเข้ารหัสอื่น ๆ มักจะมีเวลาสูงสุดในการรัน กับงูหลามบางครั้งแนวทางที่ค่อนข้างค่อนข้างแออัดเกินไป - __main__คือการเพิ่มรหัสระยะเวลาที่จะ
วิธีที่ดีในการทำโพรไฟล์ว่าโปรแกรม Python ใช้เวลานานแค่ไหน?
คำตอบ:
งูหลามรวมถึง Profiler ที่เรียกว่าcProfile ไม่เพียงให้เวลาการทำงานโดยรวมเท่านั้น แต่ยังแยกเวลาแต่ละฟังก์ชั่นแยกต่างหากและบอกให้คุณทราบว่ามีการเรียกใช้ฟังก์ชันแต่ละครั้งกี่ครั้งทำให้ง่ายต่อการพิจารณาว่าคุณควรทำการปรับแต่งที่ไหน
คุณสามารถโทรจากภายในรหัสของคุณหรือจากล่ามเช่นนี้
import cProfile
cProfile.run('foo()')มีประโยชน์มากขึ้นคุณสามารถเรียกใช้ cProfile เมื่อเรียกใช้สคริปต์:
python -m cProfile myscript.pyเพื่อให้ง่ายยิ่งขึ้นฉันได้สร้างไฟล์แบตช์เล็ก ๆ ชื่อว่า 'profile.bat':
python -m cProfile %1ดังนั้นสิ่งที่ฉันต้องทำคือเรียกใช้:
profile euler048.pyและฉันได้รับสิ่งนี้:
1007 function calls in 0.061 CPU seconds
Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}แก้ไข: Updated เชื่อมโยงไปยังแหล่งข้อมูลที่ดีจากวิดีโอ PyCon 2013 หัวข้อ 
 หลาม Profiling
นอกจากนี้ยังผ่าน YouTube
python -m cProfile -o <out.profile> <script>) RunSnakeRun ที่เรียกใช้ตามที่runsnake <out.profile>ประเมินค่าไม่ได้
                    cprofileจะแนะนำยังคงprofileมากกว่า
                    เมื่อก่อนฉันทำ pycallgraphสร้างภาพเสมือนจริงจากรหัสไพ ธ อนของคุณ แก้ไข:ฉันได้อัปเดตตัวอย่างเพื่อทำงานกับ 3.3 ซึ่งเป็นรุ่นล่าสุดของการเขียนนี้
หลังจากpip install pycallgraphและติดตั้ง GraphVizคุณสามารถเรียกใช้จากบรรทัดคำสั่ง:
pycallgraph graphviz -- ./mypythonscript.pyหรือคุณสามารถโปรไฟล์บางส่วนของรหัสของคุณ:
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()สิ่งเหล่านี้จะสร้างpycallgraph.pngไฟล์คล้ายกับภาพด้านล่าง:

Traceback (most recent call last): /pycallgraph.py", line 90, in generate     output.done()   File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 94, in done     source = self.generate()   File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 143, in generate     indent_join.join(self.generate_attributes()),   File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 169, in generate_attributes     section, self.attrs_from_dict(attrs), ValueError: zero length field name in format
                    sudo apt-get install graphvizนี้เป็นเพียง
                    เป็นค่าที่ชี้ให้เห็นว่าการใช้ตัวสร้างโปรไฟล์ใช้งานได้ (โดยค่าเริ่มต้น) บนเธรดหลักและคุณจะไม่ได้รับข้อมูลใด ๆ จากเธรดอื่น ๆ หากคุณใช้พวกเขา นี้อาจจะเป็นบิตของ gotcha ที่มันจะสมบูรณ์ไม่ได้กล่าวถึงในเอกสาร Profiler
หากคุณต้องการโพรไฟล์เธรดคุณจะต้องดูthreading.setprofile()ฟังก์ชันในเอกสารด้วย
คุณสามารถสร้างthreading.Threadคลาสย่อยของคุณเองเพื่อทำ:
class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))และใช้ProfiledThreadคลาสนั้นแทนคลาสมาตรฐาน มันอาจให้ความยืดหยุ่นแก่คุณมากกว่า แต่ฉันไม่แน่ใจว่ามันคุ้มค่าโดยเฉพาะถ้าคุณใช้รหัสบุคคลที่สามซึ่งไม่ใช้คลาสของคุณ
targetฟังก์ชั่นของเธรดซึ่งเป็นสิ่งที่การthreading.Thread.run()เรียกใช้งาน แต่ที่ผมกล่าวในคำตอบก็อาจจะไม่คุ้มค่าที่จะ subclass กระทู้ตั้งแต่รหัสของบุคคลที่สามใด ๆ threading.setprofile()ที่จะได้ใช้มันและเพื่อใช้แทน
                    python wiki เป็นหน้าที่ยอดเยี่ยมสำหรับการทำโปรไฟล์ทรัพยากร: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
เช่นเดียวกับเอกสารหลาม: http://docs.python.org/library/profile.html
ดังที่แสดงโดย Chris Lawlor cProfile เป็นเครื่องมือที่ยอดเยี่ยมและสามารถใช้พิมพ์บนหน้าจอได้อย่างง่ายดาย:
python -m cProfile -s time mine.py <args>หรือไปยังไฟล์:
python -m cProfile -o output.file mine.py <args>PS> ถ้าคุณใช้ Ubuntu ตรวจสอบให้แน่ใจว่าได้ติดตั้ง python-profile แล้ว
apt-get install python-profiler หากคุณส่งออกไปยังไฟล์คุณจะได้รับการสร้างภาพที่ดีโดยใช้เครื่องมือดังต่อไปนี้
PyCallGraph: เครื่องมือในการสร้างภาพกราฟการโทร
  ติดตั้ง:
 pip install pycallgraphวิ่ง:
 pycallgraph mine.py argsดู:
 gimp pycallgraph.pngคุณสามารถใช้สิ่งที่คุณต้องการดูไฟล์ png ฉันใช้ gimp
 
น่าเสียดายที่ฉันมักจะได้รับ
dot: กราฟมีขนาดใหญ่เกินไปสำหรับบิตแมป cairo-renderer ปรับสเกลโดย 0.257079 ให้เหมาะสม
ซึ่งทำให้ภาพของฉันเล็กผิดปกติ ดังนั้นฉันมักจะสร้างไฟล์ svg:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>PS> ตรวจสอบให้แน่ใจว่าได้ติดตั้ง graphviz (ซึ่งมีโปรแกรม dot):
pip install graphvizกราฟทางเลือกโดยใช้ gprof2dot ผ่าน @maxy / @quodlibetor:
pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg@ ความคิดเห็นของ Maxy ในคำตอบนี้ช่วยฉันได้มากพอที่ฉันคิดว่ามันสมควรคำตอบของตัวเอง: ฉันมีไฟล์. pstats ที่สร้างโดย cProfile แล้วและฉันไม่ต้องการเรียกใช้ pycallgraph อีกครั้งดังนั้นฉันจึงใช้gprof2dotและสวยมาก svgs:
$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svgและ BLAM!
มันใช้จุด (เช่นเดียวกับที่ pycallgraph ใช้) ดังนั้นเอาต์พุตจะคล้ายกัน ฉันได้รับความประทับใจที่ gprof2dot แพ้ข้อมูลน้อยลง:

pwd/gprof2dot/gprof2dot.py $ HOME / bin (หรือใช้ ln -s $ PWD / gprof2dot / gprof2dot.py ~ / bin ในเชลล์ส่วนใหญ่ - การเน้นเสียงหนักหนาสาหัสนั้นถูกจัดรูปแบบในครั้งแรก รุ่น)
                    lnรับคำสั่งโต้แย้งผิดเกือบทุกครั้ง
                    ฉันพบเครื่องมือที่มีประโยชน์ชื่อSnakeVizเมื่อค้นคว้าหัวข้อนี้ SnakeViz เป็นเครื่องมือสร้างภาพโปรไฟล์บนเว็บ มันง่ายมากที่จะติดตั้งและใช้งาน วิธีปกติที่ฉันใช้คือสร้างไฟล์สถิติด้วย%prunแล้วทำการวิเคราะห์ใน SnakeViz
เทคนิคหลัก ได้แก่ ใช้แผนภูมิ Sunburstดังแสดงด้านล่างซึ่งลำดับชั้นของการเรียกใช้ฟังก์ชันถูกจัดเรียงเป็นเลเยอร์ของส่วนโค้งและข้อมูลเวลาที่เข้ารหัสในความกว้างเชิงมุม
สิ่งที่ดีที่สุดคือคุณสามารถโต้ตอบกับแผนภูมิ ตัวอย่างเช่นหากต้องการขยายเข้าไปหนึ่งสามารถคลิกที่ส่วนโค้งและส่วนโค้งและลูกหลานของมันจะถูกขยายเป็นซ่านใหม่เพื่อแสดงรายละเอียดเพิ่มเติม
วิธีที่ง่ายและรวดเร็วที่สุดในการค้นหาว่าจะไปที่ไหนตลอดเวลา
1. pip install snakeviz
2. python -m cProfile -o temp.dat <PROGRAM>.py
3. snakeviz temp.datวาดแผนภูมิวงกลมในเบราว์เซอร์ ชิ้นที่ใหญ่ที่สุดคือฟังก์ชันที่มีปัญหา ง่ายมาก.
ฉันคิดว่าcProfileมันยอดเยี่ยมสำหรับการทำโปรไฟล์ในขณะที่kcachegrindดีสำหรับการมองเห็นผลลัพธ์ pyprof2calltreeในระหว่างที่จับแปลงไฟล์
python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltreeในการติดตั้งเครื่องมือที่จำเป็น (บน Ubuntu อย่างน้อย):
apt-get install kcachegrind
pip install pyprof2calltreeผลลัพธ์:
brew install qcachegrindและ substitude แต่ละkcachegrind  ที่มีqcachegrind ในรายละเอียดสำหรับโปรไฟล์ที่ประสบความสำเร็จ
                    export QT_X11_NO_MITSHM=1
                    นอกจากนี้มูลค่าการกล่าวขวัญก็คือตัวดูการถ่ายโอนข้อมูล GUI cProfile RunSnakeRun RunSnakeRunช่วยให้คุณสามารถจัดเรียงและเลือกได้จึงซูมเข้าในส่วนที่เกี่ยวข้องของโปรแกรม ขนาดของรูปสี่เหลี่ยมผืนผ้าในภาพเป็นสัดส่วนกับเวลาที่ถ่าย หากคุณวางเมาส์เหนือสี่เหลี่ยมมันจะไฮไลต์การโทรเข้าในตารางและทุกที่บนแผนที่ เมื่อคุณคลิกสองครั้งที่สี่เหลี่ยมมันจะซูมเข้าที่ส่วนนั้น มันจะแสดงให้คุณเห็นว่าใครเรียกส่วนนั้นและส่วนนั้นเรียกว่าอะไร
ข้อมูลเชิงอธิบายมีประโยชน์มาก มันแสดงรหัสสำหรับบิตนั้นซึ่งจะมีประโยชน์เมื่อคุณจัดการกับการเรียกใช้ไลบรารีในตัว มันบอกคุณว่าไฟล์และบรรทัดอะไรในการค้นหารหัส
ต้องการชี้ให้เห็นว่า OP พูดว่า 'ทำโปรไฟล์' แต่ดูเหมือนว่าเขาหมายถึง 'เวลา' โปรดทราบว่าโปรแกรมจะทำงานช้าลงเมื่อทำโปรไฟล์

โมดูลการทำโปรไฟล์ที่ดีคือ line_profiler (เรียกว่าการใช้สคริปต์ kernprof.py) ก็สามารถดาวน์โหลดได้ที่นี่
ความเข้าใจของฉันคือ cProfile ให้ข้อมูลเกี่ยวกับเวลาทั้งหมดที่ใช้ในแต่ละฟังก์ชันเท่านั้น ดังนั้นแต่ละบรรทัดของรหัสจะไม่หมดเวลา นี่เป็นปัญหาในการคำนวณทางวิทยาศาสตร์เนื่องจากบ่อยครั้งที่หนึ่งบรรทัดอาจใช้เวลานาน อย่างที่ฉันจำได้ cProfile ไม่ได้ใช้เวลาในการพูด numpy.dot
ฉันเพิ่งสร้างปลาทูน่าเพื่อให้เห็นภาพของ Python runtime และนำเข้าโปรไฟล์; สิ่งนี้อาจมีประโยชน์ที่นี่
ติดตั้งด้วย
pip install tunaสร้างโปรไฟล์รันไทม์
python3 -m cProfile -o program.prof yourfile.pyหรือโปรไฟล์นำเข้า (จำเป็นต้องมี Python 3.7+)
python3 -X importprofile yourfile.py 2> import.logจากนั้นก็เรียกใช้ปลาทูน่าในไฟล์
tuna program.profline_profiler(นำเสนอแล้วที่นี่) ยังได้รับแรงบันดาลใจ   pprofileซึ่งอธิบายว่า:
Line-granularity ตัวกำหนดเธรดและตัวกำหนด pure-python
มันมี line-granularity เนื่องจากline_profilerเป็น Python แท้สามารถใช้เป็นคำสั่งแบบสแตนด์อโลนหรือโมดูลและยังสามารถสร้างไฟล์รูปแบบ callgrind ที่สามารถวิเคราะห์ได้อย่างง่ายดายด้วย[k|q]cachegrindรูปแบบที่สามารถวิเคราะห์ได้อย่างง่ายดายด้วย
นอกจากนี้ยังมีvprofซึ่งเป็นแพ็คเกจ Python ที่อธิบายดังนี้:
[... ] ให้การแสดงข้อมูลแบบอินเทอร์แอคทีฟและอินเทอร์แอคทีฟสำหรับคุณลักษณะของโปรแกรม Python เช่นเวลาทำงานและการใช้หน่วยความจำ
มีคำตอบที่ดีมากมาย แต่พวกเขาอาจใช้บรรทัดคำสั่งหรือโปรแกรมภายนอกบางโปรแกรมสำหรับการทำโปรไฟล์และ / หรือเรียงลำดับผลลัพธ์
ฉันพลาดวิธีที่ฉันสามารถใช้ใน IDE ของฉัน (eclipse-PyDev) โดยไม่ต้องแตะที่บรรทัดคำสั่งหรือติดตั้งอะไร ดังนั้นนี่คือ
def count():
    from math import sqrt
    for x in range(10**5):
        sqrt(x)
if __name__ == '__main__':
    import cProfile, pstats
    cProfile.run("count()", "{}.profile".format(__file__))
    s = pstats.Stats("{}.profile".format(__file__))
    s.strip_dirs()
    s.sort_stats("time").print_stats(10)ดูเอกสารหรือคำตอบอื่น ๆ สำหรับข้อมูลเพิ่มเติม
การปฏิบัติตามคำตอบของโจวชอว์เกี่ยวกับรหัสแบบมัลติเธรดไม่ทำงานตามที่คาดไว้ฉันคิดว่าruncallวิธีการใน cProfile เป็นเพียงการทำself.enable()และself.disable()โทรไปรอบ ๆ การเรียกใช้ฟังก์ชันที่ทำโปรไฟล์ดังนั้นคุณสามารถทำได้เองและมีรหัสที่คุณต้องการ รบกวนน้อยที่สุดด้วยรหัสที่มีอยู่
cprofile.pyรหัสที่มา 's เผยให้เห็นว่าเป็นว่าสิ่งที่runcall()ทำ มีความเฉพาะเจาะจงมากขึ้นหลังจากสร้างอินสแตนซ์โปรไฟล์ด้วยprof = cprofile.Profile()โทรทันทีprof.disable()แล้วเพิ่มprof.enable()และprof.disable()โทรไปยังส่วนของรหัสที่คุณต้องการทำโปรไฟล์
                    ในแหล่งที่มาของ Virtaal มีคลาสที่มีประโยชน์มากและมัณฑนากรที่สามารถสร้างโปรไฟล์ (แม้สำหรับวิธีการ / ฟังก์ชั่นที่เฉพาะเจาะจง) นั้นง่ายมาก ผลลัพธ์นั้นสามารถดูได้อย่างสะดวกสบายใน KCacheGrind
cProfile นั้นยอดเยี่ยมสำหรับการทำโปรไฟล์อย่างรวดเร็ว แต่ส่วนใหญ่แล้วมันก็สิ้นสุดลงสำหรับฉันด้วยข้อผิดพลาด Function runctx แก้ปัญหานี้โดยการเริ่มต้นอย่างถูกต้องกับสภาพแวดล้อมและตัวแปรหวังว่ามันจะมีประโยชน์สำหรับใครบางคน:
import cProfile
cProfile.runctx('foo()', None, locals())หากคุณต้องการทำ profiler สะสมหมายถึงการเรียกใช้ฟังก์ชันหลายครั้งในแถวและดูผลรวมของผลลัพธ์
คุณสามารถใช้สิ่งนี้ cumulative_profilerมัณฑนากร :
เป็น python> = 3.6 เฉพาะ แต่คุณสามารถลบออกnonlocalเพื่อใช้กับเวอร์ชันเก่ากว่าได้
import cProfile, pstats
class _ProfileFunc:
    def __init__(self, func, sort_stats_by):
        self.func =  func
        self.profile_runs = []
        self.sort_stats_by = sort_stats_by
    def __call__(self, *args, **kwargs):
        pr = cProfile.Profile()
        pr.enable()  # this is the profiling section
        retval = self.func(*args, **kwargs)
        pr.disable()
        self.profile_runs.append(pr)
        ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
        return retval, ps
def cumulative_profiler(amount_of_times, sort_stats_by='time'):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            nonlocal function, amount_of_times, sort_stats_by  # for python 2.x remove this row
            profiled_func = _ProfileFunc(function, sort_stats_by)
            for i in range(amount_of_times):
                retval, ps = profiled_func(*args, **kwargs)
            ps.print_stats()
            return retval  # returns the results of the function
        return wrapper
    if callable(amount_of_times):  # incase you don't want to specify the amount of times
        func = amount_of_times  # amount_of_times is the function in here
        amount_of_times = 5  # the default amount
        return real_decorator(func)
    return real_decoratorตัวอย่าง
การทำโปรไฟล์ฟังก์ชัน baz 
import time
@cumulative_profiler
def baz():
    time.sleep(1)
    time.sleep(2)
    return 1
baz()baz วิ่ง 5 ครั้งและพิมพ์สิ่งนี้:
         20 function calls in 15.003 seconds
   Ordered by: internal time
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10   15.003    1.500   15.003    1.500 {built-in method time.sleep}
        5    0.000    0.000   15.003    3.001 <ipython-input-9-c89afe010372>:3(baz)
        5    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}การระบุจำนวนครั้ง
@cumulative_profiler(3)
def baz():
    ...โซลูชันเทอร์มินัลเท่านั้น (และง่ายที่สุด) ในกรณีที่ UI แฟนซีทั้งหมดเหล่านั้นล้มเหลวในการติดตั้งหรือเรียกใช้: 
ละเว้นcProfileทั้งหมดและแทนที่ด้วยpyinstrumentที่จะรวบรวมและแสดงแผนผังการโทรทันทีหลังจากดำเนินการ
ติดตั้ง:
$ pip install pyinstrumentโปรไฟล์และผลการแสดง:
$ python -m pyinstrument ./prog.pyทำงานร่วมกับ python2 และ 3
[แก้ไข] เอกสารของ API ที่สำหรับ profiling เพียงส่วนหนึ่งของรหัสที่สามารถพบได้ที่นี่
วิธีของฉันคือการใช้ yappi ( https://github.com/sumerc/yappi ) มันมีประโยชน์อย่างยิ่งเมื่อรวมกับเซิร์ฟเวอร์ RPC ที่ (แม้แต่การดีบัก) คุณลงทะเบียนวิธีการเริ่มหยุดและพิมพ์ข้อมูลการทำโปรไฟล์เช่นด้วยวิธีนี้:
@staticmethod
def startProfiler():
    yappi.start()
@staticmethod
def stopProfiler():
    yappi.stop()
@staticmethod
def printProfiler():
    stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
    statPrint = '\n'
    namesArr = [len(str(stat[0])) for stat in stats.func_stats]
    log.debug("namesArr %s", str(namesArr))
    maxNameLen = max(namesArr)
    log.debug("maxNameLen: %s", maxNameLen)
    for stat in stats.func_stats:
        nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
        log.debug('nameAppendSpaces: %s', nameAppendSpaces)
        blankSpace = ''
        for space in nameAppendSpaces:
            blankSpace += space
        log.debug("adding spaces: %s", len(nameAppendSpaces))
        statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + "\t" + str(
            round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"
    log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
    log.log(1000, statPrint)จากนั้นเมื่อโปรแกรมของคุณทำงานคุณสามารถเริ่มโปรแกรมสร้างโปรไฟล์ได้ตลอดเวลาโดยการเรียกใช้startProfilerวิธี RPC และถ่ายโอนข้อมูลการทำโปรไฟล์ไปยังไฟล์บันทึกโดยการโทรprintProfiler (หรือปรับเปลี่ยนวิธี rpc เพื่อส่งกลับไปยังผู้เรียก) และรับผลลัพธ์ดังกล่าว:
2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
name                                                                                                                                      ncall     ttot    tsub
2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
C:\Python27\lib\sched.py.run:80                                                                                                           22        0.11    0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515                                                    22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66                                       1         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464                                                                                    1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243     4         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537                                                                          1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4         0.0     0.0
<string>.__new__:8                                                                                                                        220       0.0     0.0
C:\Python27\lib\socket.py.close:276                                                                                                       4         0.0     0.0
C:\Python27\lib\threading.py.__init__:558                                                                                                 1         0.0     0.0
<string>.__new__:8                                                                                                                        4         0.0     0.0
C:\Python27\lib\threading.py.notify:372                                                                                                   1         0.0     0.0
C:\Python27\lib\rfc822.py.getheader:285                                                                                                   4         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301                                                                                  1         0.0     0.0
C:\Python27\lib\xmlrpclib.py.end:816                                                                                                      3         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467                                                                                         1         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460                                                                               1         0.0     0.0
C:\Python27\lib\SocketServer.py.close_request:475                                                                                         1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066               4         0.0     0.0 มันอาจจะไม่เป็นประโยชน์สำหรับสคริปต์สั้น ๆ แต่ช่วยในการเพิ่มประสิทธิภาพกระบวนการประเภทเซิร์ฟเวอร์โดยเฉพาะอย่างยิ่งเมื่อprintProfilerวิธีการที่สามารถเรียกหลายครั้งในช่วงเวลาเพื่อโปรไฟล์และเปรียบเทียบเช่นสถานการณ์การใช้งานโปรแกรมที่แตกต่างกัน
ใน yappi รุ่นที่ใหม่กว่ารหัสต่อไปนี้จะใช้งานได้:
@staticmethod
def printProfile():
    yappi.get_func_stats().print_all()def printProfiler():     if not yappi_available:         return      stats = yappi.get_func_stats()     stats.print_all(columns={0:("name",90), 1:("ncall", 5),                     2:("tsub", 8), 3:("ttot", 8), 4:("tavg",8)})  (ตกลงหลังจากพยายามสองครั้งเพื่อใส่รหัสบล็อกลงในความคิดเห็นที่ฉันยอมแพ้นี่เป็นเรื่องยากสำหรับเว็บไซต์ถามตอบ )
                    เครื่องมือใหม่ในการจัดการการทำโปรไฟล์ใน Python คือ PyVmMonitor: http://www.pyvmmonitor.com/
มันมีคุณสมบัติพิเศษบางอย่างเช่น
หมายเหตุ: มันเป็นโฆษณา แต่ฟรีสำหรับโอเพนซอร์ส
gprof2dot_magic
ฟังก์ชั่นเวทย์มนตร์สำหรับgprof2dotโพรไฟล์คำสั่ง Python ใด ๆ เป็นกราฟ DOT ใน JupyterLab หรือ Jupyter Notebook
GitHub repo: https://github.com/mattijn/gprof2dot_magic
การติดตั้ง
gprof2dot_magicให้แน่ใจว่าคุณได้แพคเกจหลาม
pip install gprof2dot_magicมันอ้างอิงgprof2dotและgraphvizจะถูกติดตั้งเช่นกัน
การใช้
หากต้องการเปิดใช้งานฟังก์ชั่นเวทย์มนตร์แรกให้โหลดgprof2dot_magicโมดูล
%load_ext gprof2dot_magicจากนั้นโปรไฟล์รายการคำสั่งใด ๆ เป็นกราฟ DOT เช่น:
%gprof2dot print('hello world')เคยต้องการที่จะรู้ว่าสิ่งที่สคริปต์หลามกำลังทำอะไร ป้อนเชลล์ตรวจสอบ Inspect Shell ให้คุณพิมพ์ / แก้ไขกลมและเรียกใช้ฟังก์ชั่นโดยไม่ขัดจังหวะสคริปต์ที่ทำงานอยู่ ขณะนี้มีประวัติการเติมคำสั่งอัตโนมัติ (เฉพาะบน linux)
Inspect Shell ไม่ใช่ดีบักเกอร์แบบ pdb
https://github.com/amoffat/Inspect-Shell
คุณสามารถใช้มัน (และนาฬิกาข้อมือของคุณ)
เพิ่มในhttps://stackoverflow.com/a/582337/1070617 ,
ฉันเขียนโมดูลนี้ที่ช่วยให้คุณใช้ cProfile และดูผลลัพธ์ได้อย่างง่ายดาย เพิ่มเติมได้ที่นี่: https://github.com/ymichael/cprofilev
$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.โปรดดูเพิ่มเติมที่: http://ymichael.com/2014/03/08/profiling-python-with-cprofile.htmlเกี่ยวกับวิธีการทำความเข้าใจสถิติที่เก็บรวบรวม
มันจะขึ้นอยู่กับสิ่งที่คุณต้องการดูจากโปรไฟล์ การวัดเวลาแบบง่ายสามารถทำได้โดย (ทุบตี)
time python python_prog.pyแม้แต่ '/ usr / bin / time' ก็สามารถแสดงผลตัวชี้วัดแบบละเอียดได้โดยใช้การตั้งค่าสถานะ '--verbose'
ในการตรวจสอบตัวชี้วัดเวลาที่กำหนดโดยแต่ละฟังก์ชั่นและเพื่อให้เข้าใจถึงจำนวนเวลาที่ใช้ไปกับฟังก์ชั่นได้ดีขึ้นคุณสามารถใช้ inPilt cProfile ใน python
การเข้าสู่ตัวชี้วัดที่มีรายละเอียดมากขึ้นเช่นประสิทธิภาพเวลาไม่ใช่ตัวชี้วัดเพียงอย่างเดียว คุณสามารถกังวลเกี่ยวกับหน่วยความจำเธรดและอื่น ๆ
ตัวเลือกการทำโปรไฟล์: 
1. line_profilerเป็นอีกหนึ่ง profiler ที่ใช้กันโดยทั่วไปเพื่อค้นหาตัวชี้วัดเวลาแบบทีละบรรทัด 
2. memory_profilerเป็นเครื่องมือในการใช้หน่วยความจำโปรไฟล์ 
3. heapy (จากโครงการ Guppy)โปรไฟล์วิธีใช้ออบเจ็กต์ในฮีป
เหล่านี้เป็นของทั่วไปที่ฉันมักจะใช้ แต่ถ้าคุณต้องการทราบข้อมูลเพิ่มเติมลองอ่านหนังสือเล่มนี้ มันเป็นหนังสือที่ค่อนข้างดีในการเริ่มต้นโดยคำนึงถึงประสิทธิภาพ คุณสามารถย้ายไปยังหัวข้อขั้นสูงเกี่ยวกับการใช้ Cython และ JIT (Just-in-time) เรียบเรียง
ด้วยโปรแกรมรวบรวมข้อมูลเชิงสถิติเช่นaustinไม่จำเป็นต้องใช้เครื่องมือหมายความว่าคุณสามารถดึงข้อมูลออกจากแอพพลิเคชั่น Python ได้ง่ายๆด้วย
austin python3 my_script.pyเอาท์พุทดิบไม่มีประโยชน์มาก แต่คุณสามารถไปป์ที่Flamegraph.pl เพื่อรับกราฟเปลวไฟแทนข้อมูลที่ให้การแบ่งเวลาที่ใช้ (วัดเป็นไมโครวินาทีของเรียลไทม์)
austin python3 my_script.py | flamegraph.pl > my_script_profile.svgนอกจากนี้ยังมีผู้สร้างสถิติที่เรียกว่า statprofทางสถิติที่เรียกว่า มันเป็นเครื่องมือสร้างตัวอย่างเพื่อเพิ่มค่าใช้จ่ายน้อยที่สุดให้กับรหัสของคุณและให้การกำหนดเวลาแบบอิงบรรทัด (ไม่ใช่แค่ตามฟังก์ชั่น) เหมาะสำหรับแอปพลิเคชันแบบเรียลไทม์เช่นเกม แต่อาจมีความแม่นยำน้อยกว่า cProfile
รุ่นใน pypiเป็นบิตเก่าเพื่อให้สามารถติดตั้งได้ด้วยpipโดยการระบุพื้นที่เก็บข้อมูลคอมไพล์ :
pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01คุณสามารถเรียกใช้เช่นนี้:
import statprof
with statprof.profile():
    my_questionable_function()ดูสิ่งนี้ด้วย https://stackoverflow.com/a/10333592/320036
ฉันเพิ่งพัฒนาผู้สร้างโปรไฟล์ของตัวเองซึ่งได้รับแรงบันดาลใจจาก pypref_time:
https://github.com/modaresimr/auto_profiler
โดยการเพิ่มเครื่องมือตกแต่งมันจะแสดงแผนผังของฟังก์ชั่นที่ใช้เวลานาน
@Profiler(depth=4, on_disable=show)
Install by: pip install auto_profilerimport time # line number 1
import random
from auto_profiler import Profiler, Tree
def f1():
    mysleep(.6+random.random())
def mysleep(t):
    time.sleep(t)
def fact(i):
    f1()
    if(i==1):
        return 1
    return i*fact(i-1)
def show(p):
    print('Time   [Hits * PerHit] Function name [Called from] [Function Location]\n'+\
          '-----------------------------------------------------------------------')
    print(Tree(p.root, threshold=0.5))
@Profiler(depth=4, on_disable=show)
def main():
    for i in range(5):
        f1()
    fact(3)
if __name__ == '__main__':
    main()
Time   [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974]  main  [auto-profiler/profiler.py:267]  [/test/t2.py:30]
├── 5.954s [5 * 1.191]  f1  [/test/t2.py:34]  [/test/t2.py:14]
│   └── 5.954s [5 * 1.191]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
│       └── 5.954s [5 * 1.191]  <time.sleep>
|
|
|   # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020]  fact  [/test/t2.py:36]  [/test/t2.py:20]
    ├── 0.849s [1 * 0.849]  f1  [/test/t2.py:21]  [/test/t2.py:14]
    │   └── 0.849s [1 * 0.849]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
    │       └── 0.849s [1 * 0.849]  <time.sleep>
    └── 2.171s [1 * 2.171]  fact  [/test/t2.py:24]  [/test/t2.py:20]
        ├── 1.552s [1 * 1.552]  f1  [/test/t2.py:21]  [/test/t2.py:14]
        │   └── 1.552s [1 * 1.552]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
        └── 0.619s [1 * 0.619]  fact  [/test/t2.py:24]  [/test/t2.py:20]
            └── 0.619s [1 * 0.619]  f1  [/test/t2.py:21]  [/test/t2.py:14]เมื่อฉันไม่รูทบนเซิร์ฟเวอร์ฉันใช้ lsprofcalltree.pyและเรียกใช้โปรแกรมเช่นนี้:
python lsprofcalltree.py -o callgrind.1 test.pyจากนั้นฉันสามารถเปิดรายงานด้วยซอฟต์แวร์ที่เข้ากันได้กับcallgrindเช่นqcachegrind
สำหรับการรับสถิติโพรไฟล์อย่างรวดเร็วสำหรับตัวอย่างโค้ดของคุณบนโน้ตบุ๊ก IPython หนึ่งสามารถฝัง line_profiler และ memory_profiler ลงในสมุดบันทึกของพวกเขาได้โดยตรง
!pip install line_profiler
!pip install memory_profiler%load_ext line_profiler
%load_ext memory_profiler%time print('Outputs CPU time,Wall Clock time') 
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µsให้:
%timeit -r 7 -n 1000 print('Outputs execution time of the snippet') 
#1000 loops, best of 7: 7.46 ns per loop%prun -s cumulative 'Code to profile' ให้:
%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiBให้:
#Example function
def fun():
  for i in range(10):
    print(i)
#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()ให้: