Skip to content

Commit 99891e5

Browse files
committed
Merge pull request rkern#1 from rkern/rel/1.0
1.0 Release Branch
2 parents 1828ac0 + f1d5818 commit 99891e5

File tree

12 files changed

+317
-121
lines changed

12 files changed

+317
-121
lines changed

.hgignore renamed to .gitignore

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
syntax: glob
2-
.gdb_history
1+
# Swap files.
2+
.*.swp
3+
.*.swo
4+
*~
5+
36
*.pyc
47
*.pyo
5-
*.pyclbr
68
*.so
7-
.*.swp
8-
.*.swo
9+
*.o
10+
*.a
11+
912
build/
1013
dist/
1114
_line_profiler.c

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: python
2+
python:
3+
- "3.4"
4+
- "3.3"
5+
- "3.2"
6+
- "2.7"
7+
install:
8+
- pip install --install-option='--no-cython-compile' -r dev_requirements.txt
9+
- python setup.py develop
10+
script:
11+
- python -m unittest discover -v tests
12+
notifications:
13+
email:
14+

MANIFEST.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
include LICENSE.txt
22
include LICENSE_Python.txt
3-
include README.txt
3+
include README.rst
44
include python25.pxd
55
include timers.h
66
include _line_profiler.c
77
include unset_trace.h
8+
recursive-include tests *.py

README.txt renamed to README.rst

Lines changed: 53 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,53 @@
11
line_profiler and kernprof
22
--------------------------
33

4-
line_profiler is a module for doing line-by-line profiling of functions.
5-
kernprof is a convenient script for running either line_profiler or the Python
4+
`line_profiler` is a module for doing line-by-line profiling of functions.
5+
kernprof is a convenient script for running either `line_profiler` or the Python
66
standard library's cProfile or profile modules, depending on what is available.
77

88
They are available under a `BSD license`_.
99

10-
.. _BSD license: http://packages.python.org/line_profiler/LICENSE.txt
10+
.. _BSD license: https://raw.githubusercontent.com/rkern/line_profiler/master/LICENSE.txt
1111

1212
.. contents::
1313

1414

1515
Installation
1616
============
1717

18-
Source releases and any binaries can be downloaded from the PyPI link.
18+
Releases of `line_profiler` can be installed using pip_::
1919

20-
http://pypi.python.org/pypi/line_profiler
20+
$ pip install line_profiler
2121

22-
The current release of the kernprof.py script may be downloaded separately here:
22+
Source releases and any binaries can be downloaded from the PyPI link.
2323

24-
http://packages.python.org/line_profiler/kernprof.py
24+
http://pypi.python.org/pypi/line_profiler
2525

26-
To check out the development sources, you can use Mercurial_::
26+
To check out the development sources, you can use Git_::
2727

28-
$ hg clone https://bitbucket.org/robertkern/line_profiler
28+
$ git clone https://github.com/rkern/line_profiler.git
2929

3030
You may also download source tarballs of any snapshot from that URL.
3131

32-
Source releases will require a C compiler in order to build line_profiler. In
33-
addition, Mercurial checkouts will also require Cython_ >= 0.10. Source releases
32+
Source releases will require a C compiler in order to build `line_profiler`.
33+
In addition, git checkouts will also require Cython_ >= 0.10. Source releases
3434
on PyPI should contain the pregenerated C sources, so Cython should not be
3535
required in that case.
3636

37-
kernprof.py is a single-file pure Python script and does not require a compiler.
38-
If you wish to use it to run cProfile and not line-by-line profiling, you may
39-
copy it to a directory on your PATH manually and avoid trying to build any
40-
C extensions.
37+
`kernprof` is a single-file pure Python script and does not require
38+
a compiler. If you wish to use it to run cProfile and not line-by-line
39+
profiling, you may copy it to a directory on your `PATH` manually and avoid
40+
trying to build any C extensions.
4141

42-
In order to build and install line_profiler, you will simply use the standard
43-
`build and install`_ for most Python packages::
44-
45-
$ python setup.py install
46-
47-
.. _Mercurial: http://www.selenic.com/mercurial/wiki/
42+
.. _git: http://git-scm.com/
4843
.. _Cython: http://www.cython.org
4944
.. _build and install: http://docs.python.org/install/index.html
5045

5146

5247
line_profiler
5348
=============
5449

55-
The current profiling tools supported in Python 2.5 and later only time
50+
The current profiling tools supported in Python 2.7 and later only time
5651
function calls. This is a good first step for locating hotspots in one's program
5752
and is frequently all one needs to do to optimize the program. However,
5853
sometimes the cause of the hotspot is actually a single line in the function,
@@ -75,27 +70,29 @@ of each individual line inside those functions. In a typical workflow, one only
7570
cares about line timings of a few functions because wading through the results
7671
of timing every single line of code would be overwhelming. However, LineProfiler
7772
does need to be explicitly told what functions to profile. The easiest way to
78-
get started is to use the kernprof.py script.
73+
get started is to use the `kernprof` script. ::
74+
75+
$ kernprof -l script_to_profile.py
7976

80-
If you use "kernprof.py [-l/--line-by-line] script_to_profile.py", an instance
81-
of LineProfiler will be created and inserted into the __builtins__ namespace
82-
with the name "profile". It has been written to be used as a decorator, so in
83-
your script, you can decorate any function you want to profile with @profile. ::
77+
`kernprof` will create an instance of LineProfiler and insert it into the
78+
`__builtins__` namespace with the name `profile`. It has been written to be
79+
used as a decorator, so in your script, you can decorate any function you want
80+
to profile with @profile. ::
8481

8582
@profile
8683
def slow_function(a, b, c):
8784
...
8885

89-
The default behavior of kernprof is to put the results into a binary file
90-
script_to_profile.py.lprof . You can tell kernprof to immediately view the
86+
The default behavior of `kernprof` is to put the results into a binary file
87+
script_to_profile.py.lprof . You can tell `kernprof` to immediately view the
9188
formatted results at the terminal with the [-v/--view] option. Otherwise, you
9289
can view the results later like so::
9390

9491
$ python -m line_profiler script_to_profile.py.lprof
9592

9693
For example, here are the results of profiling a single function from
9794
a decorated version of the pystone.py benchmark (the first two lines are output
98-
from pystone.py, not kernprof)::
95+
from `pystone.py`, not `kernprof`)::
9996

10097
Pystone(1.1) time for 50000 passes = 2.48
10198
This machine benchmarks at 20161.3 pystones/second
@@ -148,21 +145,11 @@ line. There are six columns of information.
148145
If you are using IPython, there is an implementation of an %lprun magic command
149146
which will let you specify functions to profile and a statement to execute. It
150147
will also add its LineProfiler instance into the __builtins__, but typically,
151-
you would not use it like that. For IPython 0.10, you can install it by editing
152-
the IPython configuration file ~/.ipython/ipy_user_conf.py to add the following
153-
lines::
154-
155-
# These two lines are standard and probably already there.
156-
import IPython.ipapi
157-
ip = IPython.ipapi.get()
158-
159-
# These two are the important ones.
160-
import line_profiler
161-
ip.expose_magic('lprun', line_profiler.magic_lprun)
148+
you would not use it like that.
162149

163150
For IPython 0.11+, you can install it by editing the IPython configuration file
164-
~/.ipython/profile_default/ipython_config.py to add the `'line_profiler'` item
165-
to the extensions list::
151+
`~/.ipython/profile_default/ipython_config.py` to add the `'line_profiler'`
152+
item to the extensions list::
166153

167154
c.TerminalIPythonApp.extensions = [
168155
'line_profiler',
@@ -200,7 +187,7 @@ the timer unit.
200187
kernprof
201188
========
202189

203-
kernprof also works with cProfile, its third-party incarnation lsprof, or the
190+
`kernprof` also works with cProfile, its third-party incarnation lsprof, or the
204191
pure-Python profile module depending on what is available. It has a few main
205192
features:
206193

@@ -224,8 +211,7 @@ features:
224211
Profiler will be instantiated and inserted into your __builtins__ with the
225212
name "profile". Like LineProfiler, it may be used as a decorator, or
226213
enabled/disabled with `enable_by_count()` and `disable_by_count()`, or
227-
even as a context manager with the "with profile:" statement in Python 2.5
228-
and 2.6.
214+
even as a context manager with the "with profile:" statement.
229215

230216
* Pre-profiling setup. With the [-s/--setup] option, you can provide
231217
a script which will be executed without profiling before executing the
@@ -324,32 +310,26 @@ Frequently Asked Questions
324310
projects for modules as small as these. However, kernprof.py is
325311
a standalone, pure Python script that can be used to do function profiling
326312
with just the Python standard library. You may grab it and install it by
327-
itself without line_profiler.
313+
itself without `line_profiler`.
328314

329-
* Do I need a C compiler to build line_profiler? kernprof.py?
315+
* Do I need a C compiler to build `line_profiler`? kernprof.py?
330316

331317
You do need a C compiler for line_profiler. kernprof.py is a pure Python
332318
script and can be installed separately, though.
333319

334-
* Do I need Cython to build line_profiler?
320+
* Do I need Cython to build `line_profiler`?
335321

336322
You should not have to if you are building from a released source tarball.
337323
It should contain the generated C sources already. If you are running into
338324
problems, that may be a bug; let me know. If you are building from
339-
a Mercurial checkout or snapshot, you will need Cython to generate the
325+
a git checkout or snapshot, you will need Cython to generate the
340326
C sources. You will probably need version 0.10 or higher. There is a bug in
341327
some earlier versions in how it handles NULL PyObject* pointers.
342328

343329
* What version of Python do I need?
344330

345-
Both line_profiler and kernprof have been tested with Python 2.4-2.7.
346-
It might work with Python 2.3, but does not currently work with Python 3.x.
347-
348-
* I get negative line timings! What's going on?
349-
350-
There was a bug in 1.0b1 on Windows that resulted in this. It should be
351-
fixed in 1.0b2. If you are still seeing negative numbers, please let me
352-
know.
331+
Both `line_profiler` and `kernprof` have been tested with Python 2.7, and
332+
3.2-3.4.
353333

354334

355335
To Do
@@ -367,16 +347,27 @@ now. Maybe later. Contributions accepted!
367347
Bugs and Such
368348
=============
369349

370-
If you find a bug, or a missing feature you really want added, please post to
371-
the enthought-dev_ mailing list or email the author at
372-
350+
Bugs and pull requested can be submitted on GitHub_.
373351

374-
.. _enthought-dev : https://mail.enthought.com/mailman/listinfo/enthought-dev
352+
.. _GitHub: https://github.com/rkern/line_profiler
375353

376354

377355
Changes
378356
=======
379357

358+
1.0
359+
~~~
360+
* ENH: `kernprof.py` is now installed as `kernprof`.
361+
* ENH: Python 3 support. Thanks to the long-suffering Mikhail Korobov for being
362+
patient.
363+
* Dropped 2.6 as it was too annoying.
364+
* ENH: The `stripzeros` and `add_module` options. Thanks to Erik Tollerud for
365+
contributing it.
366+
* ENH: Support for IPython cell blocks. Thanks to Michael Forbes for adding
367+
this feature.
368+
* ENH: Better warnings when building without Cython. Thanks to David Cournapeau
369+
for spotting this.
370+
380371
1.0b3
381372
~~~~~
382373

@@ -396,4 +387,3 @@ Changes
396387
~~~~~
397388

398389
* Initial release.
399-

_line_profiler.pyx

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ cdef class LineTiming:
5858
"""
5959
cdef public object code
6060
cdef public int lineno
61-
# Note: leave at least total_time private. This should help compile under
62-
# Python 2.4.
63-
cdef PY_LONG_LONG total_time
64-
cdef long nhits
61+
cdef public PY_LONG_LONG total_time
62+
cdef public long nhits
6563

6664
def __init__(self, object code, int lineno):
6765
self.code = code
@@ -106,9 +104,9 @@ class LineStats(object):
106104
cdef class LineProfiler:
107105
""" Time the execution of lines of Python code.
108106
"""
109-
cdef public object functions
110-
cdef public object code_map
111-
cdef public object last_time
107+
cdef public list functions
108+
cdef public dict code_map
109+
cdef public dict last_time
112110
cdef public double timer_unit
113111
cdef public long enable_count
114112

@@ -186,21 +184,26 @@ cdef class LastTime:
186184
self.time = time
187185

188186

189-
cdef int python_trace_callback(object self, PyFrameObject *py_frame, int what,
187+
cdef int python_trace_callback(object self_, PyFrameObject *py_frame, int what,
190188
PyObject *arg):
191189
""" The PyEval_SetTrace() callback.
192190
"""
193-
cdef object code, line_entries, key
191+
cdef LineProfiler self
192+
cdef object code, key
193+
cdef dict line_entries, last_time
194194
cdef LineTiming entry
195195
cdef LastTime old
196196
cdef PY_LONG_LONG time
197197

198+
self = <LineProfiler>self_
199+
last_time = self.last_time
200+
198201
if what == PyTrace_LINE or what == PyTrace_RETURN:
199202
code = <object>py_frame.f_code
200203
if code in self.code_map:
201204
time = hpTimer()
202-
if code in self.last_time:
203-
old = self.last_time[code]
205+
if code in last_time:
206+
old = last_time[code]
204207
line_entries = self.code_map[code]
205208
key = old.f_lineno
206209
if key not in line_entries:
@@ -212,11 +215,13 @@ cdef int python_trace_callback(object self, PyFrameObject *py_frame, int what,
212215
if what == PyTrace_LINE:
213216
# Get the time again. This way, we don't record much time wasted
214217
# in this function.
215-
self.last_time[code] = LastTime(py_frame.f_lineno, hpTimer())
218+
last_time[code] = LastTime(py_frame.f_lineno, hpTimer())
216219
else:
217220
# We are returning from a function, not executing a line. Delete
218-
# the last_time record.
219-
del self.last_time[code]
221+
# the last_time record. It may have already been deleted if we
222+
# are profiling a generator that is being pumped past its end.
223+
if code in last_time:
224+
del last_time[code]
220225

221226
return 0
222227

dev_requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Cython

0 commit comments

Comments
 (0)