如何计算几个cProfile结果的平均结果? [英] How to calculate the average result of several cProfile results?

查看:68
本文介绍了如何计算几个cProfile结果的平均结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

而不是像这样只运行一次配置文件:

Instead of only running the profile one time like this:

import cProfile

def do_heavy_lifting():
    for i in range(100):
        print('hello')

profiller = cProfile.Profile()
profiller.enable()

do_heavy_lifting()

profiller.disable()
profiller.print_stats(sort='time')

个人资料结果如下:

      502 function calls in 0.000 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   100    0.000    0.000    0.000    0.000 {built-in method builtins.print}
   200    0.000    0.000    0.000    0.000 cp1252.py:18(encode)
   200    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}
     1    0.000    0.000    0.000    0.000 test.py:2(do_heavy_lifting)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

我想运行几次并打印平均结果,以获得更好的精度.

I would like to run several times and print the average results, for better precision.

这是我想到的初始脚本配方:

This is a initial script recipe I thought of:

import cProfile

def do_heavy_lifting():
    for i in range(100):
        print('hello')

def best_of_profillings(target_profile_function, count):
    profile_results = []

    for index in range(count):
        profiller = cProfile.Profile()
        profiller.enable()

        target_profile_function()

        profiller.disable()
        profile_results.append(profiller)

    profile_results /= count
    return profile_results

heavy_lifting_result = best_of_profillings(do_heavy_lifting, 10)
heavy_lifting_result.print_stats(sort='time')

运行后,它应该像第一个版本一样显示结果,但不同的是它们是多次运行的平均值,而不是运行一次.

After running this, it should display the results like its first version did, but the difference is that they are the average of several runs, instead of running it one time.

草稿脚本仍然缺少 profile_results/= count 部分,在所有迭代之后,我将获得所有计算结果并创建平均结果并始终将其显示在屏幕上:

The draft script still missing the part profile_results /= count where after all the iterations, I would get all the computed results and create the average results and display it on the screen always:

      502 function calls in 0.000 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   100    0.000    0.000    0.000    0.000 {built-in method builtins.print}
   200    0.000    0.000    0.000    0.000 cp1252.py:18(encode)
   200    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}
     1    0.000    0.000    0.000    0.000 test.py:2(do_heavy_lifting)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

推荐答案

我设法使用 average() 函数创建了以下代码.我打开了 pstats 的实现并观察到有一个名为 Stats.add() 的函数,它似乎只是将结果连接到当前对象中:https://docs.python.org/3.7/library/profile.html#pstats.Stats添加

I managed to create the following code, with the function average(). I opened the implementation of pstats and observed there is a function called Stats.add() which seems to just concatenate results into the current object: https://docs.python.org/3.7/library/profile.html#pstats.Stats.add

import io
import pstats
import cProfile

def do_heavy_lifting():
    for i in range(100):
        print('hello')

def average(stats, count):
    stats.total_calls /= count
    stats.prim_calls /= count
    stats.total_tt /= count

    for func, source in stats.stats.items():
        cc, nc, tt, ct, callers = source
        stats.stats[func] = ( cc/count, nc/count, tt/count, ct/count, callers )

    return stats

def best_of_profillings(target_profile_function, count):
    output_stream = io.StringIO()
    profiller_status = pstats.Stats( stream=output_stream )

    for index in range(count):
        profiller = cProfile.Profile()
        profiller.enable()

        target_profile_function()

        profiller.disable()
        profiller_status.add( profiller )

        print( 'Profiled', '%.3f' % profiller_status.total_tt, 'seconds at', index,
                'for', target_profile_function.__name__, flush=True )

    average( profiller_status, count )
    profiller_status.sort_stats( "time" )
    profiller_status.print_stats()

    return "\nProfile results for %s\n%s" % ( 
           target_profile_function.__name__, output_stream.getvalue() )

heavy_lifting_result = best_of_profillings( do_heavy_lifting, 10 )
print( heavy_lifting_result )

结果:

Profile results for do_heavy_lifting
         102.0 function calls in 0.001 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    100.0    0.001    0.000    0.001    0.000 {built-in method builtins.print}
      1.0    0.000    0.000    0.001    0.001 D:\test.py:5(do_heavy_lifting)
      1.0    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

这篇关于如何计算几个cProfile结果的平均结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆