pyutils / line_profiler

Line-by-line profiling for Python
Other
2.56k stars 118 forks source link

feat: exclude lines from timing display #235

Closed ta946 closed 7 months ago

ta946 commented 10 months ago

ignore timings for certain lines of code. eg: print, imports, initializations, debug related function calls. the timings are displayed in negative to indicate they are not included in the total time, and their percentage contribution is set to 0.

pass to the cli arg -x a space separated list of text that is matched for each line of code, which indicates that line should be ignored. kernprof.exe ... -x "print(" "import " "cv2.imshow(" "time.time()"

also add timing for the first line, usually the function definition, which shows the overall time taken by that function

my last new feature PR i promise 😁. im just being selfish with this one so I don't have to maintain a fork for this functionality, so i understand if you wouldn't want to add it.

example output:

Timer unit: 1e-06 s

Total time: 5.42434 s
File: D:/Users/TAI/CV/OpenCV/scripts/test/blank.py
Function: main at line 1

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     1         2    4933699.0    2e+06     91.0  def main():
     2         2         -8.7     -4.4      0.0      import time
     3         2    -490202.2   -2e+05      0.0      import numpy as np
     4                                           
     5         2    2453010.0    1e+06     49.7      a = np.arange(999999999, dtype='int32')
     6                                           
     7         2        -11.8     -5.9      0.0      thisTimer = time.time()
     8         2    1880785.5 940392.8     38.1      z = np.any(a < 0)
     9         2       -167.7    -83.9      0.0      print('thisTimer', (round(1/(time.time()-thisTimer),1)if time.time()-thisTimer else 999), round(time.time()-thisTimer,6))
    10         2        -50.4    -25.2      0.0      print(z)
    11                                           
    12         2         -2.2     -1.1      0.0      thisTimer = time.time()
    13         2     599903.5 299951.8     12.2      z = np.min(a) < 0
    14         2       -159.4    -79.7      0.0      print('thisTimer', (round(1/(time.time()-thisTimer),1)if time.time()-thisTimer else 999), round(time.time()-thisTimer,6))
    15         2        -38.2    -19.1      0.0      print(z)
total time (filtered): 4.9337 s / 5.42434 s 
Erotemic commented 10 months ago

My initial feeling is negative on this. I don't think this feature is as generally useful as something like autoprofiling, and I want to avoid bloating the repo. My thought is that specifying -x is cumbersome and not something that users would want to repeat very often.

The overall time is also shown in the header, so I don't think it's necessary to repeat that information.

Of course if there is demand for this, then I'll reconsider.

ta946 commented 10 months ago

yep, fair enough regarding -x, i use a shortcut in my IDE that has them configured so forgot about a user having to manually enter it every time.

As for the timing in header, it only displays total time, whereas the line timing shows nhits and time per hit. so its easier for me to know how many times the function was called and its single run time. Otherwise i would need to read the line timing inside the function to figure out the nhits, then divide total time, which becomes harder if the first line in the function is a loop