代码之家  ›  专栏  ›  技术社区  ›  Evandro Coan

如何计算多个cProfile结果的平均结果?

  •  0
  • Evandro Coan  · 技术社区  · 7 年前

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

    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}
    

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

    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')
    

    运行此操作后,它应该像第一个版本一样显示结果,但区别在于它们是多次运行的平均值,而不是一次运行。

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

    0.000秒内502次函数调用
    
    订购人:内部时间
    
    ncalls tottime percall cumtime percall文件名:lineno(函数)
    100 0.000 0.000 0.000 0.000{内置方法内置.print}
    200 0.000 0.000 0.000 0.000 cp1252.py:18(编码)
    200 0.000 0.000 0.000 0.000{内置方法_codecs.charmap_encode}
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Evandro Coan    7 年前

    我使用函数创建了以下代码 average() pstats 观察到有一个函数叫做 Stats.add() 这似乎只是将结果连接到当前对象中: 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}