pyutils / line_profiler

Line-by-line profiling for Python
Other
2.74k stars 119 forks source link

Feature: %%lprun cell magic #42

Open JulianWgs opened 3 years ago

JulianWgs commented 3 years ago

Hello all,

this is a copy of an issue from the old repo:

https://github.com/rkern/line_profiler/issues/142 https://github.com/rkern/line_profiler/issues/31

Two people already made a "hacky" implementations:

https://gist.github.com/auneri/54600375aa0317b9c47e https://github.com/jdanbrown/potoo/blob/a7cc6a9/potoo/lprun_cell_magic.py

This feature would be really cool to see! The code from the second link is MIT licensed. Unfortunately I cant ping the original author here.

Erotemic commented 3 years ago

I would really encourage people not to use cell magic. Its nice for IPython and Jupyter, but it makes it harder to port your code to simple scripts. You can almost always accomplish magic with normal Python syntax.

For instance:

def profile_now(func):
    """
    Eagerly report profile information after each call to `func`.
    Args:
        func (Callable): function to profile
    Example:
        >>> # xdoctest: +SKIP
        >>> def func_to_profile():
        >>>     list(range(10))
        >>>     tuple(range(100))
        >>>     set(range(1000))
        >>> profile_now(func_to_profile)()  # xdoctest: +IGNORE_WANT
        Total time: 3.8e-05 s
        Function: func_to_profile at line 1
        Line #      Hits         Time  Per Hit   % Time  Line Contents
        ==============================================================
             1                                           def func_to_profile():
             2         1          4.0      4.0     10.5      list(range(10))
             3         1          3.0      3.0      7.9      tuple(range(100))
             4         1         31.0     31.0     81.6      set(range(1000))
    """
    import line_profiler
    profile = line_profiler.LineProfiler()
    new_func = profile(func)
    new_func.profile_info = KernprofParser(profile)
    new_func.print_report = new_func.profile_info.print_report

    def wraper(*args, **kwargs):
        retval = new_func(*args, **kwargs)
        new_func.print_report()
        return retval
    wraper.new_func = new_func
    return wraper

https://github.com/Erotemic/xdev/blob/master/xdev/profiler.py#L44

burnpanck commented 3 years ago

@Erotemic: I agree that magics do not belong into scripts, but I believe that is irrelevant here. When porting code from a notebook to a script, very rarely should line-profiling even be in there - neither with nor without magic. On the other hand, if I have a notebook cell in my interactive work that takes too long, just dumping %%lprun in front would be very useful.

dhirschfeld commented 1 year ago

This would be a very useful feature to have when running interactively in a jupyter notebook.