Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Time Unit with Kernprof

I've started looking for bottlenecks in Python using line_profiler. Right now, I am doing that by running

kernprof -l -v myFile.py

However, the unit of time seems to be at 1e-6, which lead to output results such as 132329040. How can I increase the time interval to make the output more readable for larger time deltas?

like image 276
FooBar Avatar asked Feb 08 '15 18:02

FooBar


3 Answers

That is a feature so far only present via Jupyter line magic, as discussed here. It can be accessed via the "-u" flag, followed by the timer unit, in seconds. This is a sample usage:

def m():
  return [0]*10**8

%lprun -u 1e-3 -f m m()

Which displays the output with timer unit in milliseconds:

Out:
Timer unit: 0.001 s

Total time: 0.363548 s
File: 
Function: m at line 1

Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def m():
2 1 363.5 363.5 100.0 return [0]*10**8

As documented in this PR.

like image 90
Pepino Avatar answered Oct 12 '22 02:10

Pepino


I find the solution by reading LineProfiler source code. you can use the following parameter "output_unit" to change the time unit.

profiler.print_stats(output_unit=1e-03)

output_unit=1e-03, the console will output "Timer unit: 0.001 s" output_unit=1, the console will output "Timer unit: 1 s"

like image 39
yafang Avatar answered Oct 12 '22 01:10

yafang


In show_func function; around line num 202:

if output_unit is None:
    output_unit = unit

Change it to:

if output_unit is None:
    output_unit = unit*1000000

Secondly, in the function show_text; around line num 254:

if output_unit is not None:
    stream.write('Timer unit: %g s\n\n' % output_unit)
else:
    stream.write('Timer unit: %g s\n\n' % unit)

Change it to:

if output_unit is not None:
    stream.write('Timer unit: %g s\n\n' % output_unit)
else:
    stream.write('Timer unit: %g s\n\n' % (unit*1000000))

Use the same factor in both places.

I have made the above changes as I use line commands to run line_profiler and not ipython/jupyter.

The output file looks like following. The time units are so much more readable!

executed
Wrote profile results to test.py.lprof
Timer unit: 0.1 s

Total time: 1.00024 s
File: test.py
Function: testfunc at line 5

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     5                                           @profile
     6                                           def testfunc():
     7         1         10.0     10.0    100.0      time.sleep(1)
     8         1          0.0      0.0      0.0      print('executed')
like image 34
Abhishek Jain Avatar answered Oct 12 '22 00:10

Abhishek Jain