Skip to main content
added 603 characters in body
Source Link
Jiby
  • 161
  • 3

Unintended consequence : What happens to your timer if timeit fails because of an exception thrown ? Do you still want your timer ?

(Ipython) magic !

It seems you're just wrapping around timeit (which is cool on functionality, but too verbose for me) : if you're prototyping with ipython lying around, you can just use %timeit test_case.format(__name__, test_function, A, B)

Best practice is using lproflprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

The solutionI needed in my currentlast project was to usea way of logging the performance of expensive calls. I used a class and the with statement.

This, which can be called like so :

Limitation is it uses directly the logging module, disregarding the current logger, but that can be worked around.

If you want to repeat the call for averaging, there might be a way of doing that (but I don't see it just now).

It seems you're just wrapping around timeit (which is cool on functionality, but too verbose for me) : if you're prototyping with ipython lying around, you can just use %timeit test_case.format(__name__, test_function, A, B)

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

The solution in my current project was to use a class and the with statement.

This can be called like so :

Limitation is it uses directly the logging module, disregarding the current logger, but that can be worked around

Unintended consequence : What happens to your timer if timeit fails because of an exception thrown ? Do you still want your timer ?

(Ipython) magic !

It seems you're just wrapping around timeit (which is cool on functionality, but too verbose for me) : if you're prototyping with ipython lying around, you can just use %timeit test_case.format(__name__, test_function, A, B)

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

I needed in my last project a way of logging the performance of expensive calls. I used a class and the with statement, which can be called like so :

Limitation is it uses directly the logging module, disregarding the current logger, but that can be worked around.

If you want to repeat the call for averaging, there might be a way of doing that (but I don't see it just now).

added 603 characters in body
Source Link
Jiby
  • 161
  • 3

Your code

EDITIt seems you're just wrapping around timeit : Sorry I answered way(which is cool on functionality, but too fastverbose for me) : if you're prototyping with ipython lying around, you can just use %timeit test_case.format(__name__, test_function, A, B)

This is simpler to type, and willcan be editing my answer to incorporate feedback ontuned YOUR code(number of repetitions ...) just like the timeit module (which it calls under the hood). See ipython Magic for that.

Lprof

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

Extending on ipython, you can even call %lprun as a magic if you install it correctly. See the Github page for more info.

My solution

EDIT : Sorry I answered way too fast, and will be editing my answer to incorporate feedback on YOUR code.

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

Your code

It seems you're just wrapping around timeit (which is cool on functionality, but too verbose for me) : if you're prototyping with ipython lying around, you can just use %timeit test_case.format(__name__, test_function, A, B)

This is simpler to type, and can be tuned (number of repetitions ...) just like the timeit module (which it calls under the hood). See ipython Magic for that.

Lprof

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

Extending on ipython, you can even call %lprun as a magic if you install it correctly. See the Github page for more info.

My solution

Source Link
Jiby
  • 161
  • 3

EDIT : Sorry I answered way too fast, and will be editing my answer to incorporate feedback on YOUR code.

Best practice is using lprof which gives you a line by line timing. But lprof is a profiler through which you run your calls, rather than a timer you can trigger.

The solution in my current project was to use a class and the with statement.

This can be called like so :

with Functimer("Expensive Function call"):
    foo = expensiveFunction(bar)

and shows up in log as

Starting expensive function call ...
Expensive function call over in 24s

You can use the info extra parameter to trigger the function timer as a logging.info rather than logging.debug (default).

Limitation is it uses directly the logging module, disregarding the current logger, but that can be worked around

I got the idea from a python recipe, I'll try to find it again. Here's the code

class FuncTimer:
""" Convenience class to time function calls

Use via the "with" keyword ::

    with Functimer("Expensive Function call"):
        foo = expensiveFunction(bar)

A timer will be displayed in the current logger as `"Starting expensive function call ..."`
then when the code exits the with statement, the log will mention `"Finished expensive function call in 28.42s"`

By default, all FuncTimer log messages are written at the `logging.DEBUG` level. For info-level messages, set the
`FuncTimer.info`  argument to `True`::

    with Functimer("Expensive Function call",info=True):
        foo = expensiveFunction(bar)
"""

def __init__(self, funcName, info=False):
    self.funcName = funcName
    self.infoLogLevel = info

def __enter__(self):
    if self.infoLogLevel:
        logging.info("Starting {} ...".format(self.funcName))
    else:
        logging.debug("Starting {} ...".format(self.funcName))
    self.start = time.clock()
    return self

def __exit__(self, *args):
    self.end = time.clock()
    self.interval = self.end - self.start
    if self.infoLogLevel:
        logging.info("{} over in {}s".format(self.funcName, self.interval).capitalize())
    else:
        logging.debug("{} over in {}s".format(self.funcName, self.interval).capitalize())