12

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?

FooBar
  • 15,724
  • 19
  • 82
  • 171
  • The time unit seems to be set in the timer.c code so unless changing that you could divide by 1000000 – Padraic Cunningham Feb 08 '15 at 19:39
  • If the reason you are doing this is to find "bottlenecks" (as opposed to measuring for the sake of measuring), [*there's a completely different way to do it.*](http://stackoverflow.com/a/4299378/23771) Measurements of time are completely beside the point. – Mike Dunlavey Feb 08 '15 at 21:03

5 Answers5

9

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.

Pepino
  • 310
  • 2
  • 10
5

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"

yafang
  • 51
  • 1
  • 3
1

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')
Abhishek Jain
  • 568
  • 2
  • 4
  • 15
0

As mentioned by @mbv above, this is now available with latest line_profiler, as of PR#34 (See PR#22 for more details), which allows one to use --unit command line option for kernprof, such as:

$ kernprof -l -v --unit 1e-3 myFile.py # milliseconds
$ kernprof -l -v --unit 1e-9 myFile.py # nanoseconds

etc.

tallamjr
  • 1,272
  • 1
  • 16
  • 21
-2

use "ms" to display:

edit line_profiler.py -> show_func -> find for lineno, nhits, time in timings: this line -> change time to time * 10-03

tuxpy
  • 1
  • 1
  • that's not a very convenient way to change the source code every time you want to change the time unit. – marscher Nov 21 '19 at 13:21