代码之家  ›  专栏  ›  技术社区  ›  fmark

我的python脚本花时间在哪里?我的cprofile/pstats跟踪中是否存在“丢失时间”?

  •  2
  • fmark  · 技术社区  · 16 年前

    我正在尝试分析一个长时间运行的python脚本。该脚本使用 gdal module . 该脚本当前使用三个文件,主脚本在光栅像素上循环,称为 find_pixel_pairs.py ,一个简单的缓存 lrucache.py 以及一些其他课程 utils.py . 我已经在中等大小的数据集上分析了代码。 pstats 返回:

       p.sort_stats('cumulative').print_stats(20)
       Thu May  6 19:16:50 2010    phes.profile
    
       355483738 function calls in 11644.421 CPU seconds
    
       Ordered by: cumulative time
       List reduced from 86 to 20 due to restriction <20>
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            1    0.008    0.008 11644.421 11644.421 <string>:1(<module>)
            1 11064.926 11064.926 11644.413 11644.413 find_pixel_pairs.py:49(phes)
    340135349  544.143    0.000  572.481    0.000 utils.py:173(extent_iterator)
      8831020   18.492    0.000   18.492    0.000 {range}
       231922    3.414    0.000    8.128    0.000 utils.py:152(get_block_in_bands)
       142739    1.303    0.000    4.173    0.000 utils.py:97(search_extent_rect)
       745181    1.936    0.000    2.500    0.000 find_pixel_pairs.py:40(is_no_data)
       285478    1.801    0.000    2.271    0.000 utils.py:98(intify)
       231922    1.198    0.000    2.013    0.000 utils.py:116(block_to_pixel_extent)
       695766    1.990    0.000    1.990    0.000 lrucache.py:42(get)
      1213166    1.265    0.000    1.265    0.000 {min}
      1031737    1.034    0.000    1.034    0.000 {isinstance}
       142740    0.563    0.000    0.909    0.000 utils.py:122(find_block_extent)
       463844    0.611    0.000    0.611    0.000 utils.py:112(block_to_pixel_coord)
       745274    0.565    0.000    0.565    0.000 {method 'append' of 'list' objects}
       285478    0.346    0.000    0.346    0.000 {max}
       285480    0.346    0.000    0.346    0.000 utils.py:109(pixel_coord_to_block_coord)
          324    0.002    0.000    0.188    0.001 utils.py:27(__init__)
          324    0.016    0.000    0.186    0.001 gdal.py:848(ReadAsArray)
            1    0.000    0.000    0.160    0.160 utils.py:50(__init__)
    

    前两个调用包含主循环-整个分析。剩余的通话时间总计不到11644秒中的625次。剩下的11000秒花在哪里?都在主回路里吗 查找像素对.py ?如果是,我能找出哪行代码占用了大部分时间吗?

    4 回复  |  直到 8 年前
        1
  •  1
  •   unutbu    16 年前

    你说得对,大部分时间都花在 phes 第49行的函数 find_pixel_pairs.py . 想知道更多,你得分手 菲斯 进入更多子功能,然后重新编译。

        2
  •  1
  •   Community Mohan Dere    9 年前

    忘记函数和度量。 Use this technique. 只需在调试模式下运行它,然后执行ctrl-c几次。调用堆栈将精确地显示哪些代码行负责该时间。

    添加:例如,暂停10次。如果,正如eol所说,11000秒中的10400秒被直接花费在 phes ,然后在其中大约9次暂停时,它将停止 就在那里 。 另一方面,如果它在某个调用自 菲斯 ,然后您不仅可以看到它在该子例程中的位置,还可以看到调用它的行,这些行还负责调用堆栈的时间等。

    Don't measure. Capture.

        3
  •  0
  •   Eric O. Lebigot    16 年前

    花在 代码执行 每个函数或方法的 tottime 列。这个 cumtime 方法是 临时 +在调用的函数中花费的时间。

    在您的列表中,您可以看到您正在寻找的11000秒是由 phes 功能本身。它只需要大约600秒。

    因此,你想找出什么需要时间 菲斯 ,按照~unutbu的建议,将其分解成子功能并重新归档。

        4
  •  0
  •   tdube    8 年前

    如果您已经确定了 phes 功能/方法 find_pixel_pairs.py ,您可以使用 line_profiler 要逐行获取这样的执行概要文件性能数字(从另一个问题复制 here ):

    Timer unit: 1e-06 s
    
    Total time: 9e-06 s
    File: <ipython-input-4-dae73707787c>
    Function: do_other_stuff at line 4
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         4                                           def do_other_stuff(numbers):
         5         1            9      9.0    100.0      s = sum(numbers)
    
    Total time: 0.000694 s
    File: <ipython-input-4-dae73707787c>
    Function: do_stuff at line 7
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         7                                           def do_stuff(numbers):
         8         1           12     12.0      1.7      do_other_stuff(numbers)
         9         1          208    208.0     30.0      l = [numbers[i]/43 for i in range(len(numbers))]
        10         1          474    474.0     68.3      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
    

    有了这些信息 需要打破 菲斯 分为多个子函数,因为您可以精确地看到哪些行的执行时间最长。

    既然你提到你的脚本运行时间很长,我建议使用 测线仪 尽可能限制方法的数量,因为在分析增加额外开销的同时,行分析可以增加更多。