我的python脚本在哪里花时间?我的CPROFILE / PSTATS跟踪中是否存在“丢失时间”?
-
03-10-2019 - |
题
我正在尝试介绍一个长期运行的python脚本。该脚本对栅格GIS数据集进行了一些空间分析 GDAL模块. 。该脚本当前使用三个文件,即循环的主脚本 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。剩下的11,000秒在哪里?这一切都在主要循环范围内吗 find_pixel_pairs.py
?如果是这样,我可以找出大部分时间都需要哪种代码?
解决方案
您是对的,大多数时候都花在 phes
在第49行的功能 find_pixel_pairs.py
. 。要了解更多信息,您需要分手 phes
进入更多的子功能,然后重新启动。
其他提示
花在 代码执行 每个功能或方法的 tottime
柱子。这 cumtime
方法是 tottime
+在调用函数上花费的时间。
在您的列表中,您会发现您要寻找的11,000秒直接由 phes
功能本身。它所说的仅需大约600秒。
因此,您想找到需要时间的时间 phes
, ,如〜unutbu所建议的那样,通过将其分解为子功能和重载。
如果您已经确定了在 phes
功能/方法 find_pixel_pairs.py
, , 您可以使用 line_profiler
要获得类似这样的逐线执行配置文件绩效编号(从另一个问题复制 这里):
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))]
有了这些信息,您会这样做 不是 需要休息 phes
将其分为多个子功能,因为您可以精确地看到哪个行的执行时间最高。
由于您提到您的脚本很长,因此我建议使用 line_profiler
在尽可能有限的方法上,因为在分析增加了额外的开销时,线条分析可以添加更多。